1. 什么是加密
加密是将明文数据通过某种特殊算法处理,使其成为一段不可读的代码,称为密文。密文可以通过密钥解密还原为明文。通过这样的途径,可以保护数据在传输的过程不会被非法窃取、阅读的目的。
2. 加密算法分类
2.1 对称加密
DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高。
2.2 非对称加密
RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的。
ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。
DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准)
3 数字签名与验名签证
3.1 数字签名
使用私钥对发送的消息进行加密的过程。
3.2 签名验证
使用公钥对被加密的消息进行解密验证的过程。
4 使用RSA实现签名与验证
4.1 下载STM32 cryptographic firmware library
STM32 已经将在要摘要、签名、验证所有API实现并生成了库,可以直接使用。STM32 cryptographic firmware library
4.2 使用openssl生成私钥和公钥
4.2.1 openssl下载
方法1:可以直接下载安装Git,git bash已经集成了openssl,减少很多安装的步骤。推荐。
方法2:从官网下载openssl
4.2.2 生成私钥
打开git bash在命令行下输入命令, openssl genrsa -out myPrivatekey.pem
生成的私钥为.pem格式。
4.2.3 生成公钥
输入命令:openssl rsa -in MyPrivatekey.pem -pubout -out MyPubkey.pem
生成的公钥为.pem格式。
至此私钥和密钥都已经生成了,但.pem格式的文件单片机无法操作,要将.pem格式转换为单片机可以识别的格式。
4.2.4 将私钥和公钥的参数打印
将私钥的各个参数打印出来,命令:openssl rsa -in MyPrivatekey.pem -text -noout
,结果如下:
$ openssl rsa -in MyPrivatekey.pem -text -noout
RSA Private-Key: (2048 bit, 2 primes)
modulus:
00:c5:ff:c3:20:e1:a6:d4:ef:2b:96:10:d3:9e:bb:
26:6a:6c:74:53:bc:c1:4d:6f:0e:18:26:d3:b1:d6:
fb:6e:8a:08:e1:01:30:8c:b4:e9:66:57:ed:47:09:
bf:bc:05:94:af:51:5d:42:a9:0c:66:3d:1d:00:07:
12:f8:b3:6b:98:01:2f:b7:12:bf:76:bb:c4:cb:64:
95:e3:a9:35:07:1d:50:b9:2b:bc:51:b4:21:c2:03:
07:5b:a9:80:11:a6:8f:99:f3:2b:22:09:f0:25:de:
e6:4f:0f:19:bc:b1:d3:46:02:f4:0f:fa:64:8e:07:
c7:54:e5:ff:6d:28:75:cc:72:47:39:f7:44:86:b6:
38:2b:f2:91:6f:b2:91:3b:f2:29:2b:b6:66:78:57:
53:7d:ec:26:5b:57:5f:32:6f:9f:2e:42:9d:9f:55:
a5:90:59:e7:28:93:db:ac:6f:8c:0c:25:f0:b1:71:
65:80:86:3e:49:4a:df:9f:f1:31:c6:f5:19:de:5c:
b9:98:70:a4:79:52:59:e0:f3:8a:e0:e6:35:82:78:
b1:1c:4d:11:9f:1e:ef:e9:ae:6f:41:53:5b:6b:2b:
04:10:ac:fd:63:10:c0:13:5d:17:6c:80:e9:7c:9a:
e8:5e:da:60:2b:4b:5e:9c:bf:14:b1:31:51:2a:56:
68:4f
publicExponent: 65537 (0x10001)
privateExponent:
00:9d:68:10:33:62:d1:23:b5:24:1c:80:32:0c:9d:
d2:13:87:37:0f:9f:1e:b9:b5:91:29:e8:2c:21:d4:
bc:3c:8b:a6:35:62:a1:bb:2a:d3:e6:95:fe:3f:9c:
63:7e:51:9d:7b:a7:1e:92:31:1c:77:67:1c:57:fa:
47:bd:c9:bd:be:b1:2a:c2:cb:37:c5:67:cf:32:b7:
3b:66:2b:0d:ca:23:27:1a:9e:c7:6e:d8:da:81:87:
b0:e0:d1:26:cc:61:73:06:3b:c8:4d:9e:42:f9:88:
73:e5:e4:26:5c:d9:ae:11:99:a5:77:d2:63:00:7a:
f4:9f:ec:dd:1c:65:af:08:a1:67:32:b2:62:8f:31:
7f:61:09:2e:6a:92:e1:2a:98:12:d7:3b:0c:b7:c4:
34:9a:e3:c0:81:95:95:89:d0:ae:fb:39:c1:15:07:
a1:18:83:ad:c5:db:1e:3b:02:45:ad:5a:78:56:af:
83:cd:51:30:be:de:0b:89:7a:85:a9:28:35:fd:49:
fb:a3:35:84:e4:83:b4:5a:e4:f6:19:c0:04:92:39:
96:d5:fe:4f:92:df:95:9a:49:b9:bc:62:04:d9:90:
dd:c6:54:36:f9:49:bd:71:b6:05:31:5d:96:ab:c7:
74:96:71:07:ed:41:7b:a4:ab:87:ce:bd:cf:2b:c0:
51:f9
prime1:
00:e5:03:14:da:58:09:3d:f1:1f:61:2f:f4:92:59:
75:a0:8c:3c:f7:58:87:d8:b6:19:8e:89:b8:4e:3c:
93:6e:7e:75:af:fb:7d:34:7f:a8:94:ef:79:bd:e4:
f3:71:d5:bc:8d:94:22:ec:f8:ad:90:14:57:2f:ed:
1b:3e:54:7f:c9:6b:3a:c8:86:9c:a0:20:db:9d:12:
00:69:4d:87:be:df:ad:97:1a:3e:9b:41:be:b7:18:
0d:d5:74:28:57:97:24:92:b6:dc:a9:d3:5c:7e:dc:
ba:b9:38:1f:a1:a3:1e:80:ed:22:66:0b:c5:dd:5a:
08:2f:e4:36:e7:e1:00:ee:bd
prime2:
00:dd:55:12:00:47:31:a6:5e:2e:13:a8:89:5b:b5:
77:ad:4e:4e:e8:5f:1b:63:0f:fd:a8:80:e8:03:10:
1d:f0:6d:8f:fd:37:8c:36:65:9c:05:04:dc:a3:44:
fd:1a:95:38:f4:bb:2f:19:b5:c9:b9:30:34:da:3f:
48:ad:26:98:0c:1c:1f:b6:17:70:4d:1d:65:32:65:
69:0f:96:b0:a1:80:19:1e:4d:f4:82:de:68:cd:b5:
99:54:21:c5:3c:21:28:c1:d9:29:ac:30:6e:9f:18:
15:a3:d3:d5:c6:83:83:63:aa:8c:ea:fe:32:26:f9:
42:db:ba:9e:40:e3:b9:79:fb
exponent1:
00:90:7d:5a:39:cc:93:c0:2e:12:d3:59:d3:60:46:
eb:2d:29:6e:09:cd:24:a0:b9:7b:f4:6f:b6:06:3e:
b7:f2:5d:fd:58:d4:3e:91:d1:fd:86:42:75:b8:36:
ec:d6:24:b9:7b:46:3c:a6:f0:db:68:ed:3c:79:33:
8b:1d:cf:68:74:a7:a0:06:06:d0:69:43:71:ec:6f:
00:2d:70:4a:36:46:a0:1a:96:e7:6b:43:96:d5:a4:
6a:8e:03:64:b4:a6:da:df:6a:5a:5d:17:ca:e3:0b:
d7:0f:a7:76:65:a0:2a:4d:c3:d0:11:3c:5a:51:a7:
4d:45:12:23:06:37:f3:43:ad
exponent2:
4b:fb:df:91:2e:df:d1:b0:b5:7a:d4:3a:4b:bc:b1:
d8:52:70:ee:7f:70:24:83:21:df:0e:5a:18:6b:19:
0c:28:60:ed:5a:7b:8d:55:36:c9:d6:50:74:d0:c3:
5f:b3:e8:f8:c3:a6:38:da:5a:e5:73:b2:41:56:c6:
79:83:2d:61:c2:e9:f4:16:79:dc:4f:82:25:5a:01:
46:73:c2:31:bf:8b:60:06:fd:31:4c:6f:88:67:96:
ba:f6:59:02:fa:93:46:71:6a:48:0d:dc:7c:4b:c5:
6a:17:d8:65:2d:53:17:0d:3f:11:91:b0:e0:06:64:
b8:90:89:b1:d7:3c:1e:af
coefficient:
00:84:19:73:65:06:bc:f5:73:38:ea:6a:d4:99:bc:
69:94:05:2d:3c:be:c5:91:0a:9b:e7:78:99:fa:76:
69:29:d9:6d:7e:20:a9:83:d6:08:a8:93:14:c4:46:
7b:51:73:3f:96:2a:fa:67:38:7b:25:18:d6:ef:c9:
1d:c6:e2:a6:ca:52:35:3b:82:32:bf:7f:a5:12:06:
78:0b:3e:66:18:a0:07:74:c9:e1:b4:1e:91:01:59:
25:ae:e0:e8:a7:c0:3a:76:bd:8a:75:63:73:40:75:
2e:c5:ec:57:4d:6d:3d:0a:7e:f2:c7:62:0e:0c:66:
33:db:e8:43:6f:e2:76:f1:f4
将公钥各个参数打印出来,命令:openssl rsa -in MyPubKey.pem -text -pubin -noout
,结果如下:
$ openssl rsa -in MyPubKey.pem -text -pubin -noout
RSA Public-Key: (2048 bit)
Modulus:
00:c5:ff:c3:20:e1:a6:d4:ef:2b:96:10:d3:9e:bb:
26:6a:6c:74:53:bc:c1:4d:6f:0e:18:26:d3:b1:d6:
fb:6e:8a:08:e1:01:30:8c:b4:e9:66:57:ed:47:09:
bf:bc:05:94:af:51:5d:42:a9:0c:66:3d:1d:00:07:
12:f8:b3:6b:98:01:2f:b7:12:bf:76:bb:c4:cb:64:
95:e3:a9:35:07:1d:50:b9:2b:bc:51:b4:21:c2:03:
07:5b:a9:80:11:a6:8f:99:f3:2b:22:09:f0:25:de:
e6:4f:0f:19:bc:b1:d3:46:02:f4:0f:fa:64:8e:07:
c7:54:e5:ff:6d:28:75:cc:72:47:39:f7:44:86:b6:
38:2b:f2:91:6f:b2:91:3b:f2:29:2b:b6:66:78:57:
53:7d:ec:26:5b:57:5f:32:6f:9f:2e:42:9d:9f:55:
a5:90:59:e7:28:93:db:ac:6f:8c:0c:25:f0:b1:71:
65:80:86:3e:49:4a:df:9f:f1:31:c6:f5:19:de:5c:
b9:98:70:a4:79:52:59:e0:f3:8a:e0:e6:35:82:78:
b1:1c:4d:11:9f:1e:ef:e9:ae:6f:41:53:5b:6b:2b:
04:10:ac:fd:63:10:c0:13:5d:17:6c:80:e9:7c:9a:
e8:5e:da:60:2b:4b:5e:9c:bf:14:b1:31:51:2a:56:
68:4f
Exponent: 65537 (0x10001)
5 代码实现
5.1 数字签名
方法一 签名耗时10~11s:
//需要先解析私钥再使用私钥签名:
retval = cmox_rsa_setKey(&Rsa_PrivateKey,
Modulus, sizeof(Modulus),
Private_Exponent, sizeof(Private_Exponent));
这里Modulus和Private_Exponent对应这前面私钥打印出来的参数,将那些参数对应填入即可。
/* Compute directly the signature passing all the needed parameters */
retval = cmox_rsa_pkcs1v22_sign(&Rsa_Ctx, /* RSA context */
&Rsa_PrivateKey, /* RSA key to use */
Computed_Hash, /* Digest to sign */
CMOX_RSA_PKCS1V22_HASH_SHA256, /* Method used to compute the digest */
Salt, sizeof(Salt), /* Random salt */
Computed_Signature, &computed_size); /* Data buffer to receive signature */
方法二 签名耗时3~4s:
需要先解析私钥再使用私钥签名:
retval = cmox_rsa_setKeyCRT(&Rsa_PrivateKey,
sizeof(Modulus) * 8, /* Private key modulus bit length */
P_Prime_Exponent, sizeof(P_Prime_Exponent), /* P prime */
Q_Prime_Exponent, sizeof(Q_Prime_Exponent), /* Q prime */
P_Prime, sizeof(P_Prime), /* P prime exponent */
Q_Prime, sizeof(Q_Prime), /* Q prime exponent */
Coefficient, sizeof(Coefficient)); /* Coefficient */
同样需要填入对应的私钥参数
/* Compute directly the signature passing all the needed parameters */
retval = cmox_rsa_pkcs1v22_sign(&Rsa_Ctx, /* RSA context */
&Rsa_PrivateKey, /* RSA key to use */
Computed_Hash, /* Digest to sign */
CMOX_RSA_PKCS1V22_HASH_SHA256, /* Method used to compute the digest */
Salt, sizeof(Salt), /* Random salt */
Computed_Signature, &computed_size); /* Data buffer to receive signature */
5.2 签名验证
验签耗时100ms左右:
需要先解析公钥再使用公钥签名:
retval = cmox_rsa_setKey(&Rsa_PlubicKey, /* RSA key structure to fill */
Modulus, sizeof(Modulus), /* Key modulus */
Public_Exponent, sizeof(Public_Exponent)); /* Public key exponent */
同样是将打印出来的公钥参数填入。
retval = cmox_rsa_pkcs1v22_verify(&Rsa_Ctx, /* RSA context */
&Rsa_PlubicKey, /* RSA key to use */
Computed_Hash, /* Digest to sign */
CMOX_RSA_PKCS1V22_HASH_SHA256, /* Method used to compute the digest */
sizeof(Salt), /* Random salt length */
Computed_Signature, sizeof(Computed_Signature), /* Signature to verify */
&fault_check); /* Fault check variable:
to ensure no fault injection occurs during this API call */