*
本文只讨论一个问题,在非对称加密算法RSA中,什么是公钥什么是私钥html
非对称加密算法有不少,例如RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。java
在在这些算法中,RSA最为经常使用,所以,在没有特殊说明的状况下,常说的公钥、私钥都指的是RAS的公钥、私钥。算法
这里也是以RSA算法为例,来讨论非对称加密中的公钥和私钥 。安全
要想了解公钥和私钥的区别,就要从它们的产生开始。
这里我默认读者已经了解了RSA算法。若是还不了解,请先去看这两篇文章。
RSA算法原理(一)
RSA算法原理(二)
特别是 RSA算法原理(二)必定要仔细看一遍,否则下面的内容你将看不懂。bash
看过上面两篇文章的人应该已经知道了,在RSA加密算法中有6个很是关键数字,他们是算法的核心。
这6个数字分别是函数
其中(n,e)在一块儿组成了公钥,(n,d)在一块儿组成了私钥。工具
如今让咱们来回答最开始提出是问题,什么是公钥,什么是私钥。
答:公钥为(n,e) 私钥为(n,d)学习
文章到此结束,谢谢你们的阅读!编码
其实咱们仔细想一想就会发现,(n,e) 和 (n,d) 根本没什么区别。为何一个叫公钥一个叫私钥呢?反过来行不行?加密
答案是能够的,根据算法原理咱们知道,只有 (n,e) 是算不出 (n,d) 的,反过来只有 (n,d) 也是算不出 (n,e) 的。因此反过来也是安全的。
那咱们就不经思考了,既然反过来也能够,那公钥私钥还有什么区别,为何一个叫公钥,一个叫私钥呢。
我想了好久,最终想到了一个合理的解释,被公开的秘钥就叫公钥,没有被公开的秘钥就叫私钥。网上多数的回答也证明了个人想法。
原来 公钥和私钥并非根据 (n,e) 和 (n,d) 区分的,而是根据使用上的不一样来区分的
让咱们再思考一个问题。
在工做中,咱们常常会用到各类生成秘钥的工具。这些工具通常会为咱们生成两个文件。一个公钥文件,假设叫public.key。一个私钥文件,假设叫private.key。
根据上文的结论,咱们是否能将private.key当作公钥公开,将public.key当作私钥,保留呢?
答案是 不能够!!!你们千万别去这么作!
为何,按照上文的结论 “被公开的秘钥就叫公钥,未被公开的秘钥就叫私钥”,不该该是能够吗?为何不能够?
除非,上面的结论是错的!!!
是的,上面的结论是错的,公钥和私钥并非根据使用上的不一样来区分的,也不是根据(n,e) 和 (n,d) 来区分的。
那公钥和私钥是经过什么来区分的,到底有没有区别。
别着急,让咱们先来看一个有趣的现象
在一些秘钥生成工具中,有一个功能叫作 根据私钥推导出公钥 ,这个功能能够根据私钥文件,推导出公钥文件来。 好比蚂蚁金服的秘钥生成工具
学习了RSA算法原理的人确定想说,这不可能,无论私钥是(n,d)仍是(n,e) ,只有 (n,e) 是算不出 (n,d) 的,只有 (n,d) 也是算不出 (n,e) 的。
难道是阿里的人太nb了,能够算出来吗?
固然不是!要真是这样,这种加密算法就不安全了。
那这个功能是怎么实现的了!
答案是私钥中包含了公钥信息!!!
让咱们作个实验,随便用什么秘钥生成工具,生成一对秘钥,而后以文本的方式打开,你会发现,私钥的内容老是比公钥的多! 再仔细观察你会发现 公钥中的部份内容在私钥中也存在!
这里最好用文本对比工具,这样看的比较清楚,我知道大家懒得去动手,因此我帮大家作好了!
为何会这样, 公钥难道不是(n,e) 私钥难道不是(n,d) 吗!
按照RSA算法的定义,公钥确实是(n,e) 私钥也确实的(n,d)。
可是,实际应用中,人们发现,这样作的话,公钥和私钥的重要性和地位就同样了,但其实咱们最关心的是私钥,私钥才是最重要的。
因而
在pkcs标准中,pkcs#1规定,私钥包含(n,e,d,p,q),公钥包含(n,e)
在pkcs标准中,pkcs#1规定,私钥包含(n,e,d,p,q),公钥包含(n,e)
在pkcs标准中,pkcs#1规定,私钥包含(n,e,d,p,q),公钥包含(n,e)
重要的话说三遍
(pkcs全称Public-Key Cryptography Standards (公开秘钥加密标准),旗下包含十几个子标准,每一个子标准负责一个领域。)
这样作有两个好处
(从上文咱们了解到,理论和实现仍是有区别的,理论跟偏向原理,而实现更偏向使用,因此实际中的私钥会比理论中的私钥多几个参数。)
如今咱们能够回答最开始提出的问题了,在非对称加密算法RSA中,什么是公钥什么是私钥。
在实际应用中,绝大多数对RSA的实现,都遵循pkcs的标准,即私钥能推出公钥,但公钥不能推出私钥
经过上面的文章咱们至少要知道如下几点
生成的秘钥通常会经过PEM编码成文原本存储。具体以下:
公钥是不分 pkcs1 格式和 pkcs8格式的,由于公钥就只有一种语法格式。
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
(n,e)
复制代码
RSAPrivateKey ::= SEQUENCE {
version Version, //版本
modulus INTEGER, // RSA合数模 n
publicExponent INTEGER, //RSA公开幂 e
privateExponent INTEGER, //RSA私有幂 d
prime1 INTEGER, //n的素数因子p
prime2 INTEGER, //n的素数因子q
exponent1 INTEGER, //值 d mod (p-1)
exponent2 INTEGER, //值 d mod (q-1)
coefficient INTEGER, //CRT系数 (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
(n,e,d,p,q)
复制代码
pkcs#8 全称 Private-Key Information Syntax Standard 私钥信息语法标准,是专门为私钥而设计的规范,因此是不存在PKCS#8格式的公钥这一说
PrivateKeyInfo ::= SEQUENCE {
version Version, //版本
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, //算法标示符
privateKey PrivateKey, //私钥
attributes [0] IMPLICIT Attributes OPTIONAL
}
复制代码