密钥编码
在工作中,会进行密钥的存储和转移。常见地,密钥的存在方式如一个文件,又或者是一个16进制字符串。
本文主要探究ECC密钥的16进制字符串是如何组成的。
使用CryptoPP,生成secp256r1公私钥如下:
bash
# 私钥
0x3041020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420f8db9ea423c6a38c726aa0c3ac912ffcac2fcafe9446471550e61912777c213b
# 公钥
0x3059301306072a8648ce3d020106082a8648ce3d03010703420004e690c566c5d4bcdc484183edd8bd80d4174d33d9a1c9ffe45030334c4e8ce796dd76982a408f7a36386a1196b4c0b97da968977d1790a2d888fa1b9e862c2c85
私钥
bash
# 私钥
0x3041020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420f8db9ea423c6a38c726aa0c3ac912ffcac2fcafe9446471550e61912777c213b
私钥有134个字符,其中前70个字符是密钥的一些参数,后64个字符才是真正的私钥内容。也就是说,多次生成secp256r1私钥,得到的所有私钥的前70个字符都是相同的。
前70个字符
bash
3041020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420
可以将这70个字符拆分如下:
30 41 # 一个DER编码的结构的开始,后续有0x41字节(65字节)内容
02 01 # 接下来的内容是一个整数,内容的长度为1字节
00 # 整数的值为0
30 13 # 一个DER编码的结构的开始,后续有0x13字节(19字节)内容
06 07 # 一个对象标识符(OID)的结构的开始,内容的长度为7字节
2a8648ce3d0201 # 定义加密方法,1.2.840.10045.2.1 (ecPublicKey)
06 08 # 一个对象标识符(OID)的结构的开始,内容的长度为8字节
2a8648ce3d030107 # 定义曲线类型,1.2.840.10045.3.1.7 (prime256v1),曲线参数
04 27 # 一个EC Private Key编码的结构的开始,后续有0x27字节(39字节)内容
30 25 # 一个DER编码的结构的开始,后续有0x25字节(37字节)内容
02 01 # 接下来的内容是一个整数,内容的长度为1字节,这里是版本号
01 # 整数的值为1
04 20 # 一个EC Private Key编码的结构的开始,后续有0x20字节(32字节)内容
... # 后续内容便是32字节/64个字符/256比特的私钥内容
后64个字符
f8db9ea423c6a38c726aa0c3ac912ffcac2fcafe9446471550e61912777c213b
一个随机数。
公钥
# 公钥
0x3059301306072a8648ce3d020106082a8648ce3d03010703420004e690c566c5d4bcdc484183edd8bd80d4174d33d9a1c9ffe45030334c4e8ce796dd76982a408f7a36386a1196b4c0b97da968977d1790a2d888fa1b9e862c2c85
公钥有182个字符,其中前54个字符是密钥的一些参数,后128个字符才是真正的公钥内容。也就是说,多次生成secp256r1公钥,得到的所有公钥的前54个字符都是相同的。
前54个字符
3059301306072a8648ce3d020106082a8648ce3d03010703420004
可以将这54个字符拆分如下:
30 59 # 一个DER编码的结构的开始,后续有0x59字节(89字节)内容
30 13 # 一个DER编码的结构的开始,后续有0x13字节(19字节)内容
06 07 # 一个对象标识符(OID)的结构的开始,内容的长度为7字节
2a8648ce3d0201 # 定义加密方法,1.2.840.10045.2.1 (ecPublicKey)
06 08 # 一个对象标识符(OID)的结构的开始,内容的长度为8字节
2a8648ce3d030107 # 定义曲线类型,1.2.840.10045.3.1.7 (prime256v1),曲线参数
03 42 # 一个比特流的开始,后续有0x42字节(66字节)内容
00 04 # 前两个00不知道啥意思,后面的04代表这是未被压缩的公钥
... # 后续内容便是128个字符的公钥内容,是一个坐标点X和Y。X和Y各占64个字符。
后128个字符
e690c566c5d4bcdc484183edd8bd80d4174d33d9a1c9ffe45030334c4e8ce796dd76982a408f7a36386a1196b4c0b97da968977d1790a2d888fa1b9e862c2c85
椭圆曲线上的一个点,由两个64个字符的X和Y组成。
注意
secp256r1 和 prime256v1 都是椭圆曲线加密算法中的曲线名称,也被称为 NIST P-256。这两个名称实际上指代的是同一条椭圆曲线,只是命名方式不同。
- secp256r1:这个名称中的 "sec" 表示 "Standards for Efficient Cryptography"(高效密码学标准),"p" 表示 "prime field"(素域),"256" 表示使用了 256 位的二进制数字来表示该素域上的坐标,"r1" 表示是该素域上的第一条曲线。
- prime256v1:这个名称中的 "prime" 表示使用素数域,"256" 表示使用了 256 位的二进制数字来表示该素域上的坐标,"v1" 表示是该素域上的第一条曲线。