• 解决用SHA256算法做私钥签名时,遇到“指定的算法无效”的问题


    在上一篇随笔“记一次三方接口开发的数据加密方案”中,使用SHA256对数据进行签名时,我提到了一个异常,System.Security.Cryptography.CryptographicException "Invalid algorithm specified.",中文为“指定的算法无效”。自己用openssl命令生成的证书没有这个问题,但是网站上导出的免费证书不行,对此不想过多纠结。但是,后来使用从CFCA申请的证书,居然也不行,所以不得不对这个问题做了更深入的探究。顺便以此为切入点,学习下使用openssl命令操作证书。

     一、产生原因

    针对证书私钥采用SHA256算法对数据进行签名时,报“指定的算法无效”这一异常,我查询了不少资料,才找到问题原因,在百度上几乎什么有用的信息也搜不出来,在google上翻阅了多篇文章,才弄清楚问题的根本。 

    实际原因是RSACryptoServiceProvider依赖底层CryptoAPI来完成其工作,只有CrytoAPI支持SHA256算法的Windows版本才会启用此功能,这意味着它取决于我们用来执行加密操作的CSP(加密服务提供程序)。因为Microsoft CSP是在Rsaenh.dll上实现的,所以当我们使用SHA256对数据做签名时,函数CryptCreateHash将在后台被CALG_SHA_256的ALG_ID调用。此加密API本身不执行加密操作。它将从应用程序获得的参数重定向到所需的CSP,并且CSP代表它执行操作。所以我们得到的错误实际上来自于CSP。

    因此,为了检查我们是否可以使用SHA256,我们必须确保:

    1. 您的证书必须在支持SHA256的情况下生成。
    2. 用于生成证书的CSP必须支持SHA256。

     二、解决方案

    针对第1种情况,生成证书时我们会指定SHA256签名算法,所以只要生成了证书就不会有问题。

    我们的问题主要是出于第2种情况,生成证书指定的CSP要支持SHA256,而windows上默认导出生成的pfx文件,却没有显式指定CSP。

    我用openssl命令生成pfx时,指定了-CSP "Microsoft Enhanced RSA and AES Cryptographic Provider",所以为什么网站上申请的证书导出的pfx不支持SHA256,根本差异就在这里。

    可以通过注册表查看系统支持的CSP,位置在HKEY_LOCAL_MACHINESoftwareMicrosoftCryptographyDefaultsProvider,如图

    所以最终,我们的思路就是拿到证书后,用openssl命令来重新生成pfx证书,在命令中指定CSP。

    在线申请证书及导出后,我们拥有test.cer和test.pfx两个证书文件。

    然后使用以下三个命令导出新的pfx证书文件。

    1 //step1,pfx转pem
    2 openssl pkcs12 -in test.pfx -nodes -out test.pem
    3 //step2,pem转key
    4 openssl rsa -in test.pem -out test.key
    5 //step3,合成新的pfx
    6 openssl pkcs12 -export -in test.cer -inkey test.key -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out test2.pfx

    最终重新生成的test2.pfx,就可以使用SHA256算法做私钥签名了。

    openssl命令详解:

    • step1,pfx是包含公钥和私钥的二进制格式证书文件,有口令保护,所以执行命令时,会要求输入密码,导出的pem为base64编码格式的证书文件,同样包括公钥和私钥;
    • step2,pem导出key,key为base64编码的私钥证书文件,rsa为密钥的加密算法,如果是dsa,就写dsa;
    • step3,将base64编码格式的cer和key文件,就是公钥和私钥文件,合成二进制格式pfx文件,指定CSP。这里的cer文件要求必须是base64编码格式的,否则会报错提示“unable to load certificates”,也就是说你的cer文件是二进制格式的。当然,这里输入的公钥采用base64编码格式的pem公钥文件也是可以的。

     三、基础知识

    为了更好的理解学习操作证书的openssl命令,需要了解证书格式的一些基本知识。

    CA中心普遍采用的规范是X.509系列和PKCS(Public Key Cryptography Standards)系列(证书格式系列标准含义很丰富,具体标准可自行查询),主要用的证书格式标准:

    • x509,公钥证书

    • pcks#12,描述个人信息交换语法标准,包含公钥和私钥,有口令保护

    编码方式:

    • DER(二进制)编码
    • BASE64(ASCII)编码

    证书文件格式:

    • csr,用于向CA申请签名的请求文件格式
    • cer或crt,公钥证书,编码方式不定,多用于Windows
    • key,公钥或私钥,编码方式不定
    • pem,公或私或公私钥,BASE64编码格式,多用于Linux
    • pfx,包括公私钥,DER编码二进制格式,多用于Windows

    openssl常用命令知识:

    • cer公钥证书为x509标准格式,pfx私钥证书为PKCS#12标准格式
    • 公钥是由私钥生成的,openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
    • 查看base64编码格式公钥证书,openssl x509 -in test.cer -noout -text
    • Linux下多用pem格式,cer转pem,openssl x509 -in test.cer -out test.pem
    • 查看pfx私钥证书,应先转为pem格式,即由PKCS#12格式DER二进制编码转换为BASE64编码后查看,openssl pkcs12 -in test.pfx -nodes -out test.pem
    • 查看pem证书,openssl rsa -in test.pem -text
    • -noout 参数即无文件输出,-nodes 参数即无算法加密

    参考(查到这篇文章直接解决了本文的问题):https://hintdesk.com/2011/07/29/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/

  • 相关阅读:
    Sql server数据库设计 7
    day08作业
    day01作业
    day07作业.
    day05作业
    day04作业
    day02作业
    初学Java的一些注意事项
    day07作业
    Week03面向对象入门
  • 原文地址:https://www.cnblogs.com/jiujiduilie/p/10599229.html
Copyright © 2020-2023  润新知