为什么京东支付接口的签名算法是用私钥加密而不是用私钥签名?

2017-09-09 00:49:05 +08:00
 v4j7o9m7s2
对接京东支付的时候,发现官方文档上写着 ‘私钥证书进行加密,并进行 base64 转码,得到签名字符串 sign ’。
最开始的时候以为是笔误,想表达的是 ’私钥证书进行签名‘,但是测试之后发现真的是用私钥进行加密。
看了一下 rfc2313,发现 rsa 的确是支持用私钥加密的,但是为什么要这样做呢?是有什么安全性上的考虑吗?求解。
5994 次点击
所在节点    程序员
25 条回复
billlee
2017-09-09 03:03:29 +08:00
RSA 签名,就是用私钥做加密操作
FanWall
2017-09-09 03:12:23 +08:00
1#正解,rsa 签名本质上就是私钥加密处理后的哈希值
LxExExl
2017-09-09 03:48:10 +08:00
私钥证书其实就是私钥签名
msg7086
2017-09-09 03:55:07 +08:00
私钥签名 = 明文 + HASH(私钥加密)

本质上差不多。
msg7086
2017-09-09 04:02:03 +08:00
我上面说的好像有点问题。加密的话理论上应该用公钥做加密。但是公钥和私钥本身就是可以互换的。
比如说你手里有 key1,京东有 key2,你用 key1 做运算的话其实是相当于用公钥加密,key2 才是私钥。
这种时候 key1 可以公开,而 key2 必须保密。这种做法主要用于传输数据的保密而非认证。
不知道你说的是不是这种情况。

又如果 key1 和 key2 都是保密的,那这时候就可以同时做加密和认证了。
Shura
2017-09-09 08:01:13 +08:00
因为数字签名的原理就是私钥加密,公钥解密。
leeg810312
2017-09-09 09:23:43 +08:00
你的概念理解错了吧。公钥和私钥在数学上是相关的一对秘钥。公钥可以用私钥计算出来,但反过来极其困难,按现有技术相当于不可能或不实际,即所谓不对称算法,因此公钥当然是公开的,何来保密?只有私钥才要持有人保密。公钥加密明文,自然只能用私钥解开。反过来,用私钥加密,只能用公钥去验证是不是对应的私钥。
v4j7o9m7s2
2017-09-09 09:56:10 +08:00
@billlee
@FanWall
@LxExExl
@msg7086
@Shura
我知道 rsa 签名算法内部的实现有用到 私钥加密+ message digesting + data encoding。
我的疑问是为什么京东选择只用私钥加密来签名,而把 rsa 签名算法里面的其它部分抛弃了?
flowfire
2017-09-09 10:05:28 +08:00
@leeg810312 我觉得你理解错了吧,公钥和私钥都互相不能计算出来,公钥和私钥的唯一区别就是一个公开一个不公开。当然如果你说的不是 RSA 加密那当我没说………
superbear
2017-09-09 10:17:33 +08:00
看使用场景。
1. 加密 公钥加密
2. 签名 私钥加密

公钥私钥是成对的,公钥加密的内容只能用对应的私钥解密;反之亦然。

你这个是签名场景,签名的意思是表明这个信息是签发者发出的,而不是别人伪造的。京东拿到你的请求,用公钥解开了,一定是你的私钥加密的。私钥是保密的,支付过程中出了问题只可能是你这边私钥泄密了;而加密场景,举个例子,对方用你的公钥加密了一条消息,这条消息只有拿着私钥的人可以看到。

总之,公钥是指公开的密钥,私钥是指保密的密钥,并没有限定只能用其中的一个加密,另一个解密。
leeg810312
2017-09-09 10:22:13 +08:00
@flowfire 只有没有深入理解非对称加密体系的人才会认为公钥和私钥是可以随意互换的。非对称的 2 个秘钥必须是数学上相关的,不仅是指 2 个密码不同,而且是互相推导的难度不对称,私钥可以推导公钥,反过来难度极高。所有非对称加密体系都是这样的模式。你要是理解这些概念,就不会说这么好笑的结论了。rsa 的数学模型估计你也没有了解一个大概,可能认为非对称就是随便写 2 个秘钥就可以了。
keyfunc
2017-09-09 10:22:32 +08:00
私钥是用来签名的,不能加密吧。公钥加密,私钥解密。私钥签名,公钥验签。
leeg810312
2017-09-09 10:33:14 +08:00
@flowfire 补充一点,实际使用中不能用私钥计算公钥的情况,是因为部分库和系统将私钥计算公钥的部分参数去掉了,可不是因为算法本身不能计算。
alcarl
2017-09-09 10:37:44 +08:00
@v4j7o9m7s2 不用其他部分,可能是因为如果公钥不公开的话,私钥同样可以起到加密的作用吧。也可能数据中没有需要加密的内容也说不定,没有看接口,只能是猜的
ETiV
2017-09-09 10:45:20 +08:00
没看过京东文档,但感觉它这里加密、签名在这里的区别:

- 加密传输全密文(参数之类的也都加密在密文里),强制密文接收方解密后才能读到参数
- 签名传输明文+签名,接收方可以忽略校验签名,直接读取参数
ShareDuck
2017-09-09 11:15:52 +08:00
@leeg810312 我觉得 @flowfire 的理解才是对的,RSA 的加密体系,用 A 密钥加密的数据可以用 B 密钥解密,用 B 密钥加密的数据可以用 A 密钥解密,公、私钥本来是相对的。但主流的编程框架,实现 RSA 算法时,将 A、B 其中一个用为“公钥”,这里举例为 A 为公钥吧,但私钥他同时保存了 A 和 B,所以私钥是不能公开的,公开了就毫无意义了。私钥是同时保存了两个密钥,而不是用其中一个可以推出另外一个。密码学我也只知道皮毛,如有错误,欢迎指正。
gamexg
2017-09-09 11:27:23 +08:00
@ShareDuck #16 千万别这么理解。
公钥私钥加密的理论是大数分解,公钥是两个大素数乘积,私钥是两个大素数本身,通过私钥可以简单的计算出公钥。

解读 RSA 公钥私钥储存格式
http://www.10tiao.com/html/635/201707/2650105399/1.html


三、分析公钥
第三部分如下:
前四字节是字符串 00 00 00 81 对应整数 129,然后后面有 129 个字节,对应素数积 n。

RSA 密钥协议如下:
第六部分是 0x0241 代表第一个素数,长度为 65 字节。
第七部分是 0x0241 代表第二个素数,长度也是 65 字节。


另外如果可以控制原文,那么可以降低通过密文暴力破解密钥的难度,所以靠谱的签名机制是私钥加密 hash(原文+盐)。
ShareDuck
2017-09-09 11:55:42 +08:00
@gamexg 你的解析非常清楚明白,谢谢你。我的私钥和公钥理解概念有误。
flowfire
2017-09-09 12:23:01 +08:00
@gamexg 我刚刚去维基查了一下 RSA 的原理,我觉得应该是这么理解。
RSA 的数学理论中,根据两个大素数,计算出两个数 e 和 d 以及自己两个素数的乘积 N,最后得出 N,e 和 N,d 两个组,这两个组是完全对等的,可以互相加密解密,并且无法互相推导,但是在 RSA 标准里,为了明确区分私钥和公钥,因此将大素数本身编码进了私钥中。
flowfire
2017-09-09 12:34:57 +08:00
@gamexg #17 可能我没说清楚= =,应该是这样的
取两个大素数,p 和 q,其积为 N,然后经过运算,算出 d 和 e,那么组 [ N, d ] 和 组 [ N, e ],是完全对等的,除了分解 N 外没有其他方法互相推导,这两个组是完全可以互换的,
但是在实际操作和标准中, 将 [其中一个组 + 大素数本身 + 其他信息] base64 编码后称之为私钥,将 [另一个组 + 其他信息 ] base64 编码后称之为公钥,因此按照标准编码过后的公私钥是不能互换的。
因此公私钥不能互换是因为 [人为添加了额外信息] 而不是因为 [算法本身的问题]
@ShareDuck #18

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/389329

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX