非对称加密算法RSA中的公钥和私钥

*本文只讨论一个问题,在非对称加密算法RSA中,什么是公钥什么是私钥

非对称加密算法

非对称加密算法有很多,例如RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。

在在这些算法中,RSA最为常用,因此,在没有特殊说明的情况下,常说的公钥、私钥都指的的RAS的公钥、私钥。

这里也是以RSA算法为例,来讨论非对称加密中的公钥和私钥

RSA加密算法

要想了解公钥和私钥的区别,就要从它们的产生开始。
这里我默认读者已经了解了RSA算法。如果还不了解,请先去看这两篇文章。
RSA算法原理(一)
RSA算法原理(二)
特别是 RSA算法原理(二)一定要仔细看一遍,不然下面的内容你将看不懂。

RSA加密算法中的公钥和私钥

看过上面两篇文章的人应该已经知道了,在RSA加密算法中有6个非常关键数字,他们是算法的核心。
这6个数字分别是

  • 大质数p
  • 另一个大质数q
  • p和q的乘积n
  • n的欧拉函数φ(n)  注:φ(n) = (p-1)(q-1)
  • 一个随机整数e,1< e < φ(n),且e与φ(n) 互质
  • e对于φ(n)的模反元素d  注:所谓"模反元素"就是指有一个整数d,可以使得ed被φ(n)除的余数为1。

其中(n,e)在一起组成了公钥,(n,d)在一起组成了私钥。

现在让我们来回答最开始提出是问题,什么是公钥,什么是私钥。
答:公钥为(n,e) 私钥为(n,d)

文章到此结束,谢谢大家的阅读!

番外1

其实我们仔细想想就会发现,(n,e) 和 (n,d) 根本没什么区别。为什么一个叫公钥一个叫私钥呢?反过来行不行?

答案是可以的,根据算法原理我们知道,只有 (n,e) 是算不出 (n,d) 的,反过来只有 (n,d) 也是算不出 (n,e) 的。所以反过来也是安全的。

那我们就不经思考了,既然反过来也可以,那公钥私钥还有什么区别,为什么一个叫公钥,一个叫私钥呢。

我想了很久,最终想到了一个合理的解释,被公开的秘钥就叫公钥,没有被公开的秘钥就叫私钥。网上多数的回答也证实了我的想法。

原来 公钥和私钥并不是根据 (n,e) 和 (n,d) 区分的,而是根据使用上的不同来区分的

番外2

让我们再思考一个问题。
在工作中,我们经常会用到各种生成秘钥的工具。这些工具一般会为我们生成两个文件。一个公钥文件,假设叫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 (公开秘钥加密标准),旗下包含十几个子标准,每个子标准负责一个领域。)

这样做有两个好处

  1. 公钥和私钥的重要性和地位不再一样,私钥的重要性和地位远高于公钥,这有利于私钥的持有者。
  2. 拥有了私钥,就相当于拥有了公钥,使用起来特别方便,就算公钥弄丢了,还可以通过私钥生成出来。

(从上文我们了解到,理论和实现还是有区别的,理论跟偏向原理,而实现更偏向使用,所以实际中的私钥会比理论中的私钥多几个参数。)


现在我们可以回答最开始提出的问题了,在非对称加密算法RSA中,什么是公钥什么是私钥。

  1. 公钥首先是一种秘钥,它包含(n,e),可以被公开,不能推导出私钥
  2. 私钥首先也是一种秘钥,他有两种语法格式,pkcs#8标准语法格式的和pkcs#1标准语法格式,其中pkcs#1规定,私钥包含(n,e,d,p,q),不可以被公开,可以推导出公钥。

在实际应用中,绝大多数对RSA的实现,都遵循pkcs的标准,即私钥能推出公钥,但公钥不能推出私钥

总结

通过上面的文章我们至少要知道以下几点

  • 公钥和私钥不一样
  • 私钥可以推导出公钥,但公钥无法推导出私钥(私钥包含公钥)
  • 理论和实现 是有出入的,所以只学习理论是无法为我们解惑的,必须联系实际进行思考才能解答我们的疑问。

番外3

秘钥格式

生成的秘钥一般会通过PEM编码成文本来存储。具体如下:

  • PKCS1语法格式私钥:传统格式,PHP、.NET一般使用此格式
  • PKCS8语法格式私钥:java一般使用此格式
  • PKCS1格式和PKCS8格式的私钥,导出的公钥内容是一摸一样的

公钥是不分 pkcs1 格式和 pkcs8格式的,因为公钥就只有一种语法格式。

RSA密钥语法

RSA公钥在PKCS#1标准中定义的语法

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}
(n,e)
复制代码

RSA私钥在PKCS#1标准中定义的语法

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)
复制代码

RSA私钥在PKCS#8标准中定义的语法

pkcs#8 全称 Private-Key Information Syntax Standard 私钥信息语法标准,是专门为私钥而设计的规范,所以是不存在PKCS#8格式的公钥这一说

PrivateKeyInfo ::= SEQUENCE {  
version	Version,	//版本 
privateKeyAlgorithm	PrivateKeyAlgorithmIdentifier, 	//算法标示符 
privateKey	PrivateKey,  //私钥
attributes		[0]  IMPLICIT Attributes OPTIONAL 
} 
复制代码

转载于:https://juejin.im/post/5b135ac36fb9a01e2d702eaf

你可能感兴趣的:(php,java)