在上一篇随笔“记一次三方接口开发的数据加密方案”中,使用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_MACHINE\Software\Microsoft\Cryptography\Defaults\Provider,如图

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

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

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

 //step1,pfx转pem
openssl pkcs12 -in test.pfx -nodes -out test.pem
//step2,pem转key
openssl rsa -in test.pem -out test.key
//step3,合成新的pfx
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/

-- End

解决用SHA256算法做私钥签名时,遇到“指定的算法无效”的问题的更多相关文章

  1. win7重命名文件时 提示 “指定的设备名无效”的解决办法

    同事从mac上传一个文件夹到win7上,但是少了一张图片con.jpg.查了半天发现将备份文件改名为con.jpg时提示 “指定的设备名无效”. 谷歌了下,发现了问题所在.坑爹的win7. 从不同的系 ...

  2. Loadrunner11在新建Microsoft Word 报告时提示指定的转换无效

    HP Loadrunner11中文教程的学习基本已经结束,最后困扰我的就是这个在创建Microsoft Word 报告时不停的提示“指定的转换无效”的问题.在网上搜索了好长时间,好多朋友回答说没有生成 ...

  3. .NET Core 使用RSA算法 加密/解密/签名/验证签名

    前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...

  4. 在用easyui中做CRUD功能时,当删除一行或多行数据后再点击修改会提示你选中了多行,如何解决这个bug了?

    在用easyui中做CRUD功能时,当删除一行或多行数据后再点击修改会提示你选中了多行,如何解决这个bug了? 在删除成功后,加上这句话就可以了:$("#dg").datagrid ...

  5. 用openssl生成SSL使用的私钥和证书,并自己做CA签名(转)

    本 文记叙的是一次基于SSL的socket通讯程序开发中,有关证书,签名,身份验证相关的步骤. 我们的场景下,socket服务端是java语言编写的,客户端是c语言.使用了一个叫做matrixssl的 ...

  6. 解决docker中使用nginx做负载均衡时并发过高时的一些问题

    # 解决docker中使用nginx做负载均衡时并发过高时的一些问题 1.问题产生原因: 由于通过nginx作为负载均衡服务,在访问并发数量达到一定量级时jmeter报错. nginx日志关键信息:a ...

  7. 关于ActiveMQ+Zookeeper做集群时,解决启动报错:java.io.IOException: com/google/common/util/concurrent/internal/InternalFutureFailureAccess

    这个问题我也是无意间碰到的,之前一直是使用单机的ActiveMQ,所以也没这个问题,但是做集群时碰到这个问题,问题是这样子出现的: 首先,我准备了三台虚拟机,然后使用 Replicated Level ...

  8. 使用keytool生成公钥、私钥、证书并且读取出来,使用私钥签名jar并验证(转)

    参考链接:http://happyqing.iteye.com/blog/2139504 :https://blog.csdn.net/arjelarxfc/article/details/52461 ...

  9. C#.NET RSA 私钥签名 公钥验证签名

    C#.NET RSA 私钥签名 公钥验证签名 公钥验签 1.待签名字符串转为byte数组时,一般使用UTF8. 2.将私钥字符串(PKCS8或PKCS1格式)转为C#.NET的RSACryptoSer ...

随机推荐

  1. 洛谷P4389 付公主的背包--生成函数+多项式

    题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...

  2. web技术应用分享

    https://www.helloweba.com/nav.html      Helloweba为广大前端开发者收录了常用实用的前端资源工具,方便大家学习和查阅. https://www.hello ...

  3. Nacos集群环境的搭建与配置

    Nacos集群环境的搭建与配置 集群搭建 一.环境: 服务器环境:CENTOS-7.4-64位 三台服务器IP:192.168.102.57:8848,192.168.102.59:8848,192. ...

  4. I/O模型系列之三:IO通信模型BIO NIO AIO

    一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...

  5. k-means cluster images

    说明 慕课网上例子,使用k-means算法分类图片, 此处调试运行通过, 并添加包管理内容, 使得其他同学容易运行. 例子地址: https://github.com/fanqingsong/clus ...

  6. HTTPS加密那点事-对称、非对称加密、数字证书

    转自:[漫画]https 加密那点事 首先,HTTP协议的缺点:没有对数据进行加密,都是明文传输的.如果要改进这种明文传输的协议,该如何做呢? 对称加密: 在每次发送真实数据之前,服务器先生成一把密钥 ...

  7. 【vue】组件使用Deferred特性

    延迟加载组件 defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行. <template> <div> ...

  8. mysql 8.0~MGR多成员读一致性

    一 背景:当在读节点多成员查询时可能导致数据不一致 二 三种场景   1 读多写少  AFTER    2 读写相当  AFTER_AND_BEFORE   3 读少写多  BEFORE三 数据不一致 ...

  9. 转:Spring历史版本变迁和如今的生态帝国

    Spring历史版本变迁和如今的生态帝国     版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/bntX2jSQfEHy7/article/deta ...

  10. [经验交流] kubernetes v1.11 更新了高可用方案

    kubernetes v1.11已经发布了一段时间,和以前相比,一个显著亮点是更新了高可用方案: https://kubernetes.io/docs/setup/independent/high-a ...