探索RSA密钥格式:数字安全的建筑基石
之前,写过一篇文章,来介绍RSA的密钥格式,在之前的文章当中,感觉介绍的还差点意思,然后呢,这一篇文章,从另一个思路来介绍一下。
前置知识
这里,假设读者对于RSA有一定的了解,如果完全不了解,可以看一下我之前写过的介绍RSA的原理的文章,或者参考下相关的书籍,我们先来简单回顾一下RSA的知识。
RSA基本的概念
RSA加密是一种非对称加密算法,广泛用于数据的安全传输。它是由Ron Rivest, Adi Shamir 和 Leonard Adleman在1977年提出的,算法名字也是由他们三人姓氏的首字母组成的。
RSA的工作原理基于一个简单的数学事实:将两个大的质数相乘是容易的,但在不知道这两个质数的情况下,对其乘积进行因式分解却是非常困难的。这个困难性是RSA算法安全性的关键。
RSA加密过程涉及三个主要步骤:密钥生成、加密和解密。
-
「密钥生成」: -
选择两个大质数 p 和 q 。 -
计算 p 和 q 的乘积 n ,即。n 的长度,即其位数(这里指的是bit的位数,不是10进制下的位数),是密钥长度。 -
计算 n 的欧拉函数 。 -
选择一个整数 e ,使得 e 和互质,且。 -
计算 e 关于 的模逆 d,即 。 -
公钥是 (e, n),私钥是 (d, n)。
-
-
「加密」: -
假设有明文消息 M ,确保 。 -
加密后的密文 C 计算为。
-
-
「解密」: -
使用私钥 (d, n) 来解密密文 C, -
原始消息 M 可以通过计算 获得。
-
回顾下整个加密过程,我们来看,里卖弄涉及到的数字有什么,不考虑加密和解密,只考虑密钥生成的那一块,我们一共可以得到p、q、n、、e、d这几个数字,那么这些数字应该如何来存储,便是我们接下来要重点讨论的内容了。
RSA密钥格式
这里,我们重点,就要考虑下在RSA当中,我们如何来记录这些数据,当然,为了辅助计算,密钥还会存储一些其他的部分,这里先不聊这部分,为了讲如何记录呢,我们先来生成一个RSA的密钥吧。
这里,为了简化呢,我这里取值的key比较短,生产环境注意key长度的安全性。
原生记录
这一种是最好理解的,就是我们直接存储原始的内容,也就是按照下面的方式来进行存储
n: 3240961237
e: 65537
d: 2811812673
p: 49937
q: 64901
这一种形式,非常的人性化,这里就不多解释了。
PKCS#1格式
PKCS#1(Public-Key Cryptography Standards #1)是RSA加密的一种标准,它定义了使用RSA公钥和私钥加密的数据格式。它是由RSA Laboratories制定的一系列公钥密码学标准之一,旨在促进公钥密码学的广泛应用和标准化。
RSA公钥
在PKCS#1标准中,RSA公钥是由两部分组成:
-
「模数(n)」:这是两个质数(p和q)的乘积。这个数字的长度(比特数)是密钥的长度。在实际应用中,模数通常是1024位、2048位或更长,以确保足够的安全性。 -
「公开指数(e)」:这是一个与模数的欧拉函数(φ(n))互质的正整数。常用的值有65537(0x10001),因为它既不太大也不太小,可以避免某些类型的攻击,同时在计算上效率较高。
在ASN.1中,一个RSA公钥可以使用下面的结构表示:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
当用DER编码时,这个结构会被转换成字节序列。如果转换成PEM格式,这个序列将被Base64编码,并加上"-----BEGIN RSA PUBLIC KEY-----"和"-----END RSA PUBLIC KEY-----"。
RSA私钥
PKCS#1中定义了两种格式的RSA私钥。一种是传统的PKCS#1格式,另一种是后来在PKCS#8标准中定义的更通用的私钥格式。在PKCS#1中,私钥有以下部分:
-
「版本(version)」:标识私钥结构的版本号。对于不带CRT参数的RSA私钥,版本号为0。 -
「模数(n)」:与公钥中的模数相同。 -
「公开指数(e)」:与公钥中的公开指数相同。 -
「私有指数(d)」:用于解密或签名的秘密指数。它是在e之下模n的乘法逆元。 -
「质数1(p)」:模数n的一个因数。 -
「质数2(q)」:模数n的另一个因数。 -
「指数1(d mod (p-1))」:私有指数d对p-1取模。 -
「指数2(d mod (q-1))」:私有指数d对q-1取模。 -
「系数(q的逆元 mod p)」:质数q在模p下的乘法逆元。
在ASN.1中,一个RSA私钥可以使用下面的结构表示:
RSAPrivateKey ::= SEQUENCE {
version INTEGER,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER -- (inverse of q) mod p
}
和公钥相同,私钥可以使用DER格式编码成字节序列,并且可以进一步用PEM格式表示。
PKCS#8格式
PKCS#8是一个公钥密码学标准,用于存储和交换私钥信息。它是由RSA Laboratories的公钥加密标准(PKCS)系列中的第8部分定义的。与PKCS#1不同,PKCS#8不仅限于RSA密钥,它提供了一个通用格式,可以用来表示任何类型的私钥。
PKCS#8中私钥的结构如下:
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL
}
Version ::= INTEGER
PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
PrivateKey ::= OCTET STRING
Attributes ::= SET OF Attribute
-
「version」:表示私钥信息结构的版本号。 -
「privateKeyAlgorithm」:描述私钥使用的算法和算法相关参数的对象,例如RSA或ECDSA。 -
「privateKey」:包含私钥本身,格式取决于使用的算法。 -
「attributes」:可选字段,可以包括有关私钥的附加信息。
对于RSA算法,privateKeyAlgorithm
字段将指明使用的是RSA加密算法,并可能包含一些算法特定的参数(对于RSA通常不需要)。privateKey
字段将包含一个DER编码的RSAPrivateKey
结构,该结构是根据PKCS#1定义的。
RSAPrivateKey ::= SEQUENCE {
version INTEGER, -- 版本号,对于PKCS#1 RSA私钥通常是0
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER -- (inverse of q) mod p
}
与PKCS#1类似,PKCS#8格式的私钥通常使用ASN.1 DER编码来表示,这是一种二进制格式。它们也可以编码为PEM格式。
有关于这些格式的详细解析呢,可以看下我之前写的文章,这里不再重复描述了。
数据存储的格式
对于存储呢,其实也比较简单。
原始的字符串文本
首先呢,我们能想到的,就是上面的哪一种形式,也就是,我们直接用可显示的文本来存储具体的密钥的内容,这个的优点呢,就是直观,缺点就是这个占用的大小要更多一些,而且解析起来也不是非常好解析,至于为什么不好解析呢,是因为,我们不知道读取到那个位置来结束,可以自行写一下这个的解析方式,这里,我就不给大家写了。
PEM格式
PEM(Privacy-Enhanced Mail)格式是一种基于文本的数据编码和存储方式,最常用于存储和传输加密材料,如SSL/TLS证书和各种密钥(包括公钥、私钥)。它被广泛用于互联网的安全通信中。
核心特点
-
「文本格式」: PEM文件是基于文本的,使用Base64编码表示二进制数据,通常包括可读的头部和尾部标记,例如 -----BEGIN CERTIFICATE-----
和-----END CERTIFICATE-----
。 -
「人类可读」: 由于其为文本格式,它可以用任何文本编辑器打开和查看,这使得进行人工审核和编辑变得相对容易。 -
「多用途」: PEM格式不仅用于存储个人证书,还可以存储公钥、私钥、证书请求、证书链等。
使用场景
PEM格式非常适合需要将加密材料以文本形式共享或存储的场景。它是SSL/TLS协议中最常用的格式,几乎所有的网络安全应用程序和库(如OpenSSL)都支持PEM格式的证书和密钥。
优点
-
「普及性」: PEM格式得到了广泛的支持和使用,几乎成为了行业标准。 -
「灵活性」: PEM格式文件可以包含多种类型的加密材料,甚至可以在一个文件中包含证书链。 -
「可读性」: 文本基础使得它容易被人类读取,也便于通过电子邮件或其他文本传输手段进行共享。
缺点
-
「体积较大」: 由于使用Base64编码和附加文本标记,PEM文件通常比相同内容的DER文件要大。
DER格式
DER(Distinguished Encoding Rules)格式是一种用于加密对象(如证书、公钥、私钥等)的二进制存储格式。与PEM格式相比,它是纯二进制形式,不适合直接在文本编辑器中查看。DER是X.509证书和相关加密标准的ASN.1(Abstract Syntax Notation One)编码规则的一个实现,旨在确保加密对象的交换不会因为平台、软件或网络的差异而受到影响。
核心特点
-
「二进制格式」: DER文件是纯二进制的,这使得它的大小通常比相应的PEM格式文件小,因为PEM需要用额外的空间来存储Base64编码和开始/结束标识符。 -
「唯一编码」: 对于任何给定的数据结构,DER提供了一种唯一的编码方式,确保了数据的一致性和可验证性,这对于加密签名尤为重要。
使用场景
由于其二进制特性,DER格式文件不如PEM格式那样易于人类阅读和处理,但它非常适合于程序内部使用,特别是在需要精简数据大小或确保数据编码一致性的场景中。例如,DER格式常用于系统内部处理证书和密钥,以及在应用程序之间传输这些对象时。
优点
-
「效率」: 由于是二进制格式,处理速度快,占用空间小。 -
「一致性」: 提供了一种标准化的方式来编码加密对象,保证了不同系统和应用之间的兼容性。
缺点
-
「不易管理」: 对于人类来说,直接查看或编辑二进制文件是不便的,需要专门的工具来解读。 -
「兼容性」: 虽然绝大多数加密库和工具都支持DER,但在需要将加密材料以文本形式共享或存储在某些特定环境下时,PEM格式可能更加普遍和方便。
HEX格式
存储字节,我们除了base64,原始的字节流,还可以采用HEX编码的格式,不过这种格式吧,我好像是没有找到具体的名字,这个也简单,只需要吧DER里面的内容转换成为了HEX编码就可以了,据说有些语言支持读取这个,只不过就多一个解析,所以这个就不展开讲解了。
格式转换
看到这些格式,是不是眼花缭乱了,这里呢,给出转换的办法,因为我的工具箱发布了,所以呢,直接用工具箱转换就好了,给出几个例子,如果还有其他需求,可以留言,心情好的话,我会添加一下。
RSA的密钥生成(PKCS#1格式)
RSA的私钥转公钥
PKCS#1私钥转PKCS#8私钥
PKCS#8私钥解析
其他格式就不展示了,大部分常见格式是支持转换的。
总结
好了,我们来总结下,这里画一个思维导图吧。
参考资料
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论