概要: 本文从golang语言和c++语言的角度使用RSA和AES,从中总结需要注意的事项,
RSA的私钥格式区别:PKCS#1 和 PKCS#8是有区别的,AES的加密工作机制需要加密端和
被加密端的模式相同
RSA
RSA的私钥格式区别:PKCS#1 和 PKCS#8
PKCS#1的格式文件开头是以1
2-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
PKCS#8的格式是以下开头1
2-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
使用openssl库加载公私钥时的接口有所区别:
PKCS#1 使用接口:PEM_read_bio_RSAPublicKey()函数
PKCS#8 使用接口:PEM_read_bio_RSA_PUBKEY()函数
PKCS#1和PKCS#8的转换命令
1 | # 私钥生成两种格式 |
AES
AES的加密工作机制共有5种
- 1.电码本模式(Electronic Codebook Book (ECB));
- 2.密码分组链接模式(Cipher Block Chaining (CBC));
- 3.计算器模式(Counter (CTR));
- 4.密码反馈模式(Cipher FeedBack (CFB));
- 5.输出反馈模式(Output FeedBack (OFB))。
加密端和解密端的工作机制要一致,所以使用AES时需要理解算法使用的那种工作模式
AES加密与解密的padding问题
首先说一下,在AES加密与解密的过程中如果需要加密的数据不是16的倍数的时候,需要对原来的数据做padding操作。
padding分为以下几种,不同的padding对加密与解密有影响,所以要保证padding的方式是一致的。
- ANSI X.923
在ANSI X.923的方式下,先是填充00,最后一个字节填充padded的字节个数。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 00 00 00 00 05 | - ISO 10126
在ISO 10126的方式下,先是填充随机值,最后一个字节填充padded的字节个数。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 95 81 28 A7 05 | - PKCS7
在PKCS7的方式下,如果一共需要padded多少个字节,所有填充的地方都填充这个值。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 05 05 05 05 05 | - ISO/IEC 7816-4
在ISO/IEC 7816-4方式下,第一个填充的字节是80,后面的都填充00。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 80 00 00 00 00 | - Zero padding
在Zero padding方式下,每一个需要填充的字节都填00。
例子: | DD DD DD DD DD DD DD DD | DD DD DD 00 00 00 00 00 |
代码实现
RSA的c++的加解密
1 |
|
使用openssl的rsa接口1
2
3
4
5
6
int result = RSA_public_encrypt(data_len, data, encrypted, rsa, padding);
int result = RSA_public_decrypt(data_len, enc_data, decrypted, rsa, padding);
int result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);
int result = RSA_private_encrypt(data_len, data, encrypted, rsa, padding);
RSA的golang的加解密
1 |
|
AES的golang的加解密
1 | // 这里的分组模式是如果正好16字节时要多一个16字节(共128位) |
AES的c++的加解密
接口1
2
3
4
5
6
7
8
9
10AES_set_encrypt_key(unsigned char*)key, int, &AES_KEY) // 加密密钥
AES_set_decrypt_key(unsigned char*)key, int, &AES_KEY) // 解密密钥
//因为是对称加密所以加解密接口都用一个
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const int enc);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
参考资料: