RSA 可以做私钥加密,公钥解密吗?解密的结果还是加密之前的明文吗?

2019-03-09 16:01:37 +08:00
 GuguguguDa

下面这个博客看的我很疑惑啊

先不论私钥加密,公钥解密有没有意义

私钥加密的结果,用公钥解密,还能解出来的吗?我试了下,居然还真可以?

https://blog.csdn.net/wangqiuyun/article/details/42143957

13748 次点击
所在节点    程序员
49 条回复
3dwelcome
2019-03-09 22:19:37 +08:00
@weyou 你说的没错,但是规范就是规范,对于符合 PKCS#1 V2.1 标准的 padding 类型有好多种,都是有严格限定,不能混用的。
PADTYPE_SIGN 专用于签名报文,PADTYPE_ENCRYPT 专用于加密,PADTYPE_OAEP 结合 SHA256 算法,各司其职,各个 RSA 软件才能相互兼容。
weyou
2019-03-09 22:58:47 +08:00
@3dwelcome 是的,在实际应用中,公钥用来加密,私钥用来签名,不能互换,这是规范。但就楼主所问问题而言,RSA 算法在数学上公钥私钥其实没什么不同,任选一个作为公钥,另外一个就是私钥。任选一个用来加密另一个就可以用来解密。
andyhuzhill
2019-03-09 23:32:28 +08:00
@weyou #22 其实不是任选一个作公钥的 非对称加密还有一个特点就是 从私钥计算公钥很简单 从公钥计算私钥很困难 这也是保证公钥加密算法安全的一个因素
bp0
2019-03-09 23:42:04 +08:00
原理上没有问题。非对称密钥的本质就是用一个 key 加密,就能用另外一个 key 解密。

不过一般都是,
公钥加密,私钥签名。
公钥加密,私钥签名。
公钥加密,私钥签名。

因为你公开了的就是公钥,没公开的就是私钥。


@3dwelcome @weyou 签名是可以加上 padding 的,而且是有必要的。加了 padding 以后,保证每次生成的签名都不相同,但是都可以用同一个公钥进行验证。参考 PKCS#1 V2.2 RSASSA-PSS。

@dryadent 私钥签名(加密)和公钥验证签名(解密)是数字签名的基础,必然是可以保证安全性的。如果真不能保证,那么我们现有的数字签名体系早就崩塌了。
luckyuro
2019-03-10 00:05:03 +08:00
@andyhuzhill 不是吧,一般来说 rsa 的公私钥,只有一个的话另一个是算不出来的吧
andyhuzhill
2019-03-10 00:25:06 +08:00
@luckyuro #25 由私钥是可以计算出公钥的,所以一般只需要好好保存私钥就可以了
qwertyegg
2019-03-10 05:10:53 +08:00
这帖子一发出来就看到了,半天后回复除了 @sadan9 基本上都没抓住重点

公钥加密系统两种用法

op 提问的这个用法,叫数字签名,用私钥(加密)签名,公钥(解密)验证

另外一个就是非对称加密,用公钥加密,用私钥解密
ryd994
2019-03-10 07:42:01 +08:00
反过来这样加密就是签名算法的原理。但实际上不推荐用同一把。有可能存在如下攻击:通过观察签名数据的明文和密文之间的关系(公钥),即使不知道私钥,但也推测加密数据的明文和密文的关系(私钥),或者缩小可能的范围。目前没听说有可操作的攻击不代表以后没有。
所以 gpg 就是建议加密、鉴权、签名三种密钥不同。

@CEBBCAT 实现上是有不同的。n 和 d 组成私钥。n 和 e 组成公钥。e 可以随机选取,但一般都用 65537。也就是说,知道私钥就可以知道公钥。

@luckyuro 实际上只要你用的是常见的软件生成,比如 OpenSSL,那就是默认 65537
CEBBCAT
2019-03-10 08:22:57 +08:00
@ryd994 太感谢了😊
7DLNU56W
2019-03-10 09:27:24 +08:00
其实我感觉私钥和公钥完全是可以互换的,生成一组之后,把哪个公开那个就是公钥,自己保留的那个就是私钥。
私钥加密公钥解密通常都是签名的作用。通过公钥来验证一段内容是由私钥持有人发布的。不过现在通常签名都是用私钥加密哈希值而不是加密原文。但本质上你加密的是原文解密出来就是原文,加密的是哈希值,解密处理就是哈希值,解密结果与未加密的是一样的。
aa6563679
2019-03-10 10:14:17 +08:00
可以是可以,但公钥长度一般都不长,甚至本身是公开的。安全性不佳
tangweihua163
2019-03-10 12:30:46 +08:00
楼上一堆瞎说的。。。。。。

我在工作中经常使用这些东西,我来说说我的理解吧。

# RSA 可以用于加解密,也可以用于消息签名。

RSA 使用一对不同的密钥:公钥和私钥。公钥是公开的,你知道,别人也知道,别人也需要知道;私钥是只能持有者知道,不能泄露了,不然很麻烦。

# 加解密

A 和 B 通信,A 使用 B 的公钥和 RSA 加密算法对消息进行加密,得到密文,密文扔出去后,只有 B 使用自己的私钥才能解。
B 回复 A,B 使用 A 的公钥和 RSA 加密算法对响应数据进行加密,加密后的密文只有 A 能够解。这就保证了,数据不会被第三方获取。

当然这里面还有一些其他的问题,比如怎样获取对方的公钥,怎样确定获取到的公钥就是对方的公钥而不是中间人伪造的公钥。可以了解下 https 握手的过程,https 主要通过对称加密(比如 AES 等)方式通信,但是对称加密密钥是通过 RSA 加密传输的。

# 签名验签

RSA 可以用于消息签名,用于消息接收方确认消息发送方身份,防止伪造的消息。
A 将原始数据使用 A 的私钥进行 RSA 签名得到 Sign,原始数据附带签名一起发送给消息接收方,消息接收方 B 使用 A 的公钥、原始数据、Sign 三个要素进行验签过程,也就是使用 A 的公钥和 RSA 算发对 Sign 进行处理,用处理的结果与原始数据进行对比,如果一致,说明是 A 发送的,而且只能是 A 发送的,除非 A 的私钥泄露了。

由于 RSA 算法比较慢,而且原始数据的大小不确定,消息签名的计算和传输可能会造成很大的 cpu 和网络开销,消息签名一般是对原始数据的摘要进行签名,比如 MD5 消息摘要算法( MD5 长度固定,且不同消息 MD5 冲突的可能性很小),对应的,验签的时候对比的不不是原始数据,而是消息摘要。使用指定的消息摘要进行签名时,签名过程计算较快,而且签名结果长度也相对固定。



总之,加解密和消息签名使用 RSA 时,目的不同,一个是为了防止明文消息被第三方获取(私密性),一个是为了方便消息接收方确认消息没有被篡改(完整性)。

如有错误,烦请指出。
tangweihua163
2019-03-10 12:36:50 +08:00
还有一点,消息签名可以防止抵赖,如果一段经过签名的消息使用 A 的公钥验签通过,那就可以确定是 A 发送的,A 不能抵赖(抗抵赖性)。
tangweihua163
2019-03-10 12:39:42 +08:00
所以,加密是不用使用私钥的,公钥公开了,任何人只要获取到你的公钥就能解了。签名也不能使用公钥,没有人有办法验证,因为别人都不知道签名者的私钥。
weyou
2019-03-10 14:27:29 +08:00
@andyhuzhill 在数学意义上私钥( d,n )并不能很容易的计算出公钥( e,n ),或者说从私钥计算公钥和从公钥计算私钥的复杂度是完全一样的。之所以你实际操作中从私钥可以能计算出公钥是因为现有的 rsa 库(比如 openssl )都是选取 e 为 3 或者 65537 (为了效率考虑),私钥的 n 你知道了,e 只有两种可能,所以公钥自然就知道了。所以这不代表 rsa 算法中的公钥私钥不是对等的。

打个比方,道路右行和左行其实没有区别,但是我国交通法规定必须右行,你在实际中硬要左行,那出事故的概率肯定要大大高于右行,但你得出个结论说因为左行事故发生率高所以我们必须右行,这就是本末倒置了。
henglinli
2019-03-10 14:42:14 +08:00
非对称加密算法公私钥都可用来加解密。
但是主流用法如 tls 是非对称算法签名,即私钥加密公钥解密,其对象是对称算法的密钥。
然而高安全的应用会在 tls 链接之上再做一层认证和密钥交换,比如 tor 的 NTOR 握手。

另外,rsa 是被怀疑有后门的——虽然没有人找出来,
所以建议选择非对称算法时考虑下 curve25519,golang,erlang,openssl 等也都已支持。
本人就毕设是做过 rsa,但是在看过 tor 的设计文档后感觉已经初入门道了,感兴趣的朋友强烈建议阅读参考。

另外,公私钥是有区别的,私钥能轻易推导出公钥,但是公钥却几乎不可能“破解”出私钥,以至于某些实现的私钥数据结构中就包含公钥。
msg7086
2019-03-10 15:51:51 +08:00
https://blog.x86.men/blog/rsa-faq

专门写了一篇短文把知识点撸一下。

这一楼里大家对名词的定义全是乱的,比如私钥和私钥文件不分清,导致各种上下矛盾但又都正确的帖子层出不穷。32 楼的 @tangweihua163 更是把私钥和事实私钥概念混在一起,写得完全正确,但是完全文不对题。
tangweihua163
2019-03-10 16:34:45 +08:00
@msg7086 我只是指出楼主搞反了啊,加密不能用私钥,签名不能用公钥。另外,我说的公钥私钥是表层逻辑上的概念,并不包含底层算法原理和具体数据关系数据结构。我不知道到底是谁文不对题……我提到事实私钥这个概念了吗?😂
msg7086
2019-03-10 16:43:53 +08:00
@tangweihua163 逻辑层上的私钥和公钥是事实私钥和事实公钥。
底层算法原理中的公钥和私钥才是原始的公钥和私钥。

算法原理中的公钥和私钥是对等的,而上层因为种种原因(例如实际代码实现,参数选择,存储方式等因素)才导致了你说的这些东西。这些不是“ RSA ”的限制,而是“某种 RSA 的实现”的限制。所以我才说,针对楼主说的“ RSA ”的疑问,你的回答,内容正确但是并不对题。你回答的并不是楼主问的。
tangweihua163
2019-03-10 17:03:45 +08:00
@msg7086 你可能理解错了我的意思了,我已经说过了,签名是用私钥处理,公钥验证。公私钥在数学上对等的,只是个选择问题,但是,用私钥处理数据不能称为是加密,因为没有私密性,用公钥处理不能称为签名,可伪造。至于你说的什么事实私钥事实公钥,我觉得是多余的概念,一对密钥生成后,定下一个做公钥,一个做私钥,以后也不能改,那今后公就是公,私就是私,没有什么事实的说法,多余…

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

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

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

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

© 2021 V2EX