赞
踩
单向加密,主要是对明文的保密和摘要提取。算法包括MD5、SHA、HMAC等。
单向加密的安全性主要取决于加密结果的长度,对于同一加密算法,安全性与加密结果的长度成正比。单向加密是存在被破解的可能的,主要有暴力破解、查字典法破解和社会工学破解等。
MD5 Message-Digest Algorithm,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
MD5
值长度相同;MD5
值;MD5
值也会巨大差异;MD5
值,很小概率找到相同MD5
值相同的原数据;// MD5示例 #include <iostream> #include <string.h> #include <stdio.h> #include "openssl/md5.h" #include "openssl/evp.h" #include "openssl/bio.h" #include "openssl/buffer.h" std::string base64Encode(const char * input, int length, bool with_new_line) { BIO* bmem = NULL; BIO* b64 = NULL; BUF_MEM* bptr = NULL; b64 = BIO_new(BIO_f_base64()); if(!with_new_line) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char * buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff; } void md5(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr) { // 调用md5哈希 unsigned char mdStr[33] = {0}; MD5((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr); // 哈希后的字符串 encodedStr = std::string((const char *)mdStr); // 哈希后的十六进制串 32字节 char buf[65] = {0}; char tmp[3] = {0}; for (int i = 0; i < 32; i++) { sprintf(tmp, "%02x", mdStr[i]); strcat(buf, tmp); } buf[32] = '\0'; // 后面都是0,从32字节截断 encodedHexStr = std::string(buf); } int main(int argc, char **argv) { // 原始明文 std::string srcText = "test MD5"; std::string encryptText = ""; std::string encryptHexText = ""; std::string decryptText = ""; std::cout << "=== 原始明文 ===" << std::endl; std::cout << srcText << std::endl; std::cout << "=== md5哈希 ===" << std::endl; md5(srcText, encryptText, encryptHexText); std::cout << "摘要字符: " << base64Encode(encryptText.c_str(), encryptText.length(), false) << std::endl; std::cout << "摘要串: " << encryptHexText << std::endl; return 0; }
执行结果:
=== 原始明文 ===
test MD5
=== md5哈希 ===
摘要字符: ISpMOJ207PrPYYF6cRz4kg==
摘要串: 212a4c389db4ecfacf61817a711cf892
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。
主要包括SHA1、SHA2,SHA2包括SHA-224、SHA-256、SHA-384、SHA-512。
安全性:SHA2>SHA1>MD5
// SHA256示例 #include <iostream> #include <string.h> #include <stdio.h> #include "openssl/sha.h" #include "openssl/evp.h" #include "openssl/bio.h" #include "openssl/buffer.h" std::string base64Encode(const char * input, int length, bool with_new_line) { BIO* bmem = NULL; BIO* b64 = NULL; BUF_MEM* bptr = NULL; b64 = BIO_new(BIO_f_base64()); if(!with_new_line) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char * buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff; } void sha256(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr) { // 调用sha256哈希 unsigned char mdStr[33] = {0}; SHA256((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr); // 哈希后的字符串 encodedStr = std::string((const char *)mdStr); // 哈希后的十六进制串 32字节 char buf[65] = {0}; char tmp[3] = {0}; for (int i = 0; i < 32; i++) { sprintf(tmp, "%02x", mdStr[i]); strcat(buf, tmp); } buf[32] = '\0'; // 后面都是0,从32字节截断 encodedHexStr = std::string(buf); } int main(int argc, char **argv) { // 原始明文 std::string srcText = "test SHA256"; std::string encryptText; std::string encryptHexText; std::string decryptText; std::cout << "=== 原始明文 ===" << std::endl; std::cout << srcText << std::endl; std::cout << "=== sha256哈希 ===" << std::endl; sha256(srcText, encryptText, encryptHexText); std::cout << "摘要字符: " << base64Encode(encryptText.c_str(), encryptText.length(), false) << std::endl; std::cout << "摘要串: " << encryptHexText << std::endl; return 0; }
执行结果:
=== 原始明文 ===
test SHA256
=== sha256哈希 ===
摘要字符: pCOIxncw2JM02mtU4CvifgrwHQuR6NnwRH/mQsys0wU=
摘要串: a42388c67730d89334da6b54e02be27e
HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,它可以与任何迭代散列函数捆绑使用。
HMAC算法更像是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的Hash算法。
// HAMC示例 #include <iostream> #include <string.h> #include <stdio.h> #include "openssl/hmac.h" using namespace std; int HmacEncode(const char * algo, const char * key, unsigned int key_length, const char * input, unsigned int input_length, unsigned char * &output, unsigned int &output_length) { const EVP_MD * engine = NULL; if(strcasecmp("sha512", algo) == 0) { engine = EVP_sha512(); } else if(strcasecmp("sha256", algo) == 0) { engine = EVP_sha256(); } else if(strcasecmp("sha1", algo) == 0) { engine = EVP_sha1(); } else if(strcasecmp("md5", algo) == 0) { engine = EVP_md5(); } else if(strcasecmp("sha224", algo) == 0) { engine = EVP_sha224(); } else if(strcasecmp("sha384", algo) == 0) { engine = EVP_sha384(); } else if(strcasecmp("sha", algo) == 0) { engine = EVP_sha(); } else if(strcasecmp("md2", algo) == 0) { engine = EVP_md2(); } else { cout << "Algorithm " << algo << " is not supported by this program!" << endl; return -1; } output = (unsigned char*)malloc(EVP_MAX_MD_SIZE); HMAC_CTX ctx; HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key, strlen(key), engine, NULL); HMAC_Update(&ctx, (unsigned char*)input, strlen(input)); HMAC_Final(&ctx, output, &output_length); HMAC_CTX_cleanup(&ctx); return 0; } int main(int argc, char **argv) { if(argc < 2) { //参数指定hash算法,支持HmacEncode列举的那些 cout << "Please specify a hash algorithm!" << endl; return -1; } char key[] = "dsfjgasdss;dsfzaasdsr;dsfjgasdsr"; //secret key std::string data = "8ba5a744-f48d-4ba2-b93f-e223deqe32343dd2332";//要加密传输的数据 unsigned char * mac = NULL; unsigned int mac_length = 0; int ret = HmacEncode(argv[1], key, strlen(key), data.c_str(), data.length(), mac, mac_length); if(0 == ret) { cout << "Algorithm HMAC encode succeeded!" << endl; } else { cout << "Algorithm HMAC encode failed!" << endl; return -1; } cout << "mac length: " << mac_length << endl; cout << "mac:"; for(int i = 0; i < (int)mac_length; i++) { printf("%-03x", (unsigned int)mac[i]); } cout << endl; if(mac) { free(mac); cout << "mac is freed!" << endl; } return 0; }
执行结果:
[root@localhost ~]# ./HMACTest sha1 Algorithm HMAC encode succeeded! mac length: 20 mac:2e a7 ac fa 3b 24 18 3 bf 2b fb b6 a4 89 f6 b4 e3 16 6d cc mac is freed! [root@localhost ~]# ./HMACTest md5 Algorithm HMAC encode succeeded! mac length: 16 mac:6f 1b 72 7 95 3f ba fb f6 0 f2 66 c2 5e 2e b1 mac is freed! [root@localhost ~]# ./HMACTest sha256 Algorithm HMAC encode succeeded! mac length: 32 mac:38 c3 1e 8f a 44 39 a8 ec 4f 2a 43 fd 59 62 ba bb 19 46 f4 59 20 89 39 24 1d 35 aa af 6b de 9 mac is freed! [root@localhost ~]#
各种算法得到的摘要长度如下:
算法 | 摘要长度(字节) |
---|---|
MD2 | 16 |
MD5 | 16 |
SHA | 20 |
SHA1 | 20 |
SHA224 | 28 |
SHA256 | 32 |
SHA384 | 48 |
SHA512 | 64 |
根据密钥的对称性,分为对称加密和非对称加密。
数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
密钥较小(一般小于256bit),密钥越大,加密越强,但加密解密越慢。
优势:算法公开、计算量小,加密速度快、加密效率高,适用于大量数据的加密;
劣势:同一套密钥,安全性较低;
一种块加密算法(Block cipher),其密钥默认长度为 56 位。块加密或者叫分组加密,这种加密方法是把明文分成几个固定大小的 block 块,然后分别对其进行加密。
DES 加密算法是对密钥进行保密,而公开算法,包括加密和解密算法。这样,只有掌握了和发送方相同密钥的人才能解读由 DES加密算法加密的密文数据。因此,破译 DES 加密算法实际上就是 搜索密钥的编码。对于 56 位长度的 密钥 来说,如果用 穷举法 来进行搜索的话,其运算次数为 2 56 2 ^{56} 256 次。
// DES示例 #include <iostream> #include <string.h> #include <stdio.h> #include <vector> #include "openssl/des.h" #include "openssl/evp.h" #include "openssl/bio.h" #include "openssl/buffer.h" using namespace std; std::string base64Encode(const char * input, int length, bool with_new_line) { BIO* bmem = NULL; BIO* b64 = NULL; BUF_MEM* bptr = NULL; b64 = BIO_new(BIO_f_base64()); if(!with_new_line) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char * buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff; } // 加密 ecb模式 std::string des_encrypt(const std::string &clearText, const std::string &key) { std::string cipherText; // 密文 DES_cblock keyEncrypt; memset(keyEncrypt, 0, 8); // 构造补齐后的密钥 if (key.length() <= 8) memcpy(keyEncrypt, key.c_str(), key.length()); else memcpy(keyEncrypt, key.c_str(), 8); // 密钥置换 DES_key_schedule keySchedule; DES_set_key_unchecked(&keyEncrypt, &keySchedule); // 循环加密,每8字节一次 const_DES_cblock inputText; DES_cblock outputText; std::vector<unsigned char> vecCiphertext; unsigned char tmp[8]; for (int i = 0; i < (int)clearText.length() / 8; i++) { memcpy(inputText, clearText.c_str() + i * 8, 8); DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT); memcpy(tmp, outputText, 8); for (int j = 0; j < 8; j++) vecCiphertext.push_back(tmp[j]); } if (clearText.length() % 8 != 0) { int tmp1 = clearText.length() / 8 * 8; int tmp2 = clearText.length() - tmp1; memset(inputText, 0, 8); memcpy(inputText, clearText.c_str() + tmp1, tmp2); // 加密函数 DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT); memcpy(tmp, outputText, 8); for (int j = 0; j < 8; j++) vecCiphertext.push_back(tmp[j]); } cipherText.clear(); cipherText.assign(vecCiphertext.begin(), vecCiphertext.end()); return cipherText; } // 解密 ecb模式 std::string des_decrypt(const std::string &cipherText, const std::string &key) { std::string clearText; // 明文 DES_cblock keyEncrypt; memset(keyEncrypt, 0, 8); if (key.length() <= 8) memcpy(keyEncrypt, key.c_str(), key.length()); else memcpy(keyEncrypt, key.c_str(), 8); DES_key_schedule keySchedule; DES_set_key_unchecked(&keyEncrypt, &keySchedule); const_DES_cblock inputText; DES_cblock outputText; std::vector<unsigned char> vecCleartext; unsigned char tmp[8]; for (int i = 0; i < (int)cipherText.length() / 8; i++) { memcpy(inputText, cipherText.c_str() + i * 8, 8); DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT); memcpy(tmp, outputText, 8); for (int j = 0; j < 8; j++) vecCleartext.push_back(tmp[j]); } if (cipherText.length() % 8 != 0) { int tmp1 = cipherText.length() / 8 * 8; int tmp2 = cipherText.length() - tmp1; memset(inputText, 0, 8); memcpy(inputText, cipherText.c_str() + tmp1, tmp2); // 解密函数 DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT); memcpy(tmp, outputText, 8); for (int j = 0; j < 8; j++) vecCleartext.push_back(tmp[j]); } clearText.clear(); clearText.assign(vecCleartext.begin(), vecCleartext.end()); return clearText; } int main(int argc, char **argv) { // 原始明文 std::string srcText = "test DES"; std::string encryptText; std::string encryptHexText; std::string decryptText; std::cout << "=== 原始明文 ===" << std::endl; std::cout << srcText << std::endl; std::cout << "=== des加解密 ===" << std::endl; std::string desKey = "12345"; encryptText = des_encrypt(srcText, desKey); std::cout << "加密字符: " << std::endl; std::cout << base64Encode(encryptText.c_str(), encryptText.length(), false) << std::endl; decryptText = des_decrypt(encryptText, desKey); std::cout << "解密字符: " << std::endl; std::cout << decryptText << std::endl; return 0; }
执行结果:
=== 原始明文 ===
test DES
=== des加解密 ===
加密字符:
vmfC/L3cGBo=
解密字符:
test DES
3DES
(即Triple DES)是DES
向AES
过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES
的一个更安全的变形。它以DES
为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES
,3DES
更为安全。密钥长度默认为168
位,还可以选择128
位。
#include <iostream> #include <string.h> #include <stdio.h> #include <vector> #include "openssl/des.h" #include "openssl/evp.h" #include "openssl/bio.h" #include "openssl/buffer.h" using namespace std; std::string base64Encode(const char * input, int length, bool with_new_line) { BIO* bmem = NULL; BIO* b64 = NULL; BUF_MEM* bptr = NULL; b64 = BIO_new(BIO_f_base64()); if(!with_new_line) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char * buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff; } int Des3DesEncrypt(const std::string& rand_key, const std::string& in, std::string& out) { char out_array[10240]; char in_array[10240]; memset(out_array, 0, 10240); memset(in_array, 0, 10240); DES_key_schedule keyschedc1; DES_key_schedule keyschedc2; DES_key_schedule keyschedc3; if (rand_key.size() < 24) { return -1; } DES_set_key((DES_cblock *)rand_key.substr(0,8).c_str(), &keyschedc1); DES_set_key((DES_cblock *)rand_key.substr(8,8).c_str(), &keyschedc2); DES_set_key((DES_cblock *)rand_key.substr(16,8).c_str(), &keyschedc3); //数据不足8位的时候后面需要补齐 如果是取余为0,则补8个0 int data_rest = in.size()%8; char ch = 8-data_rest; int len = (in.size()/8 + 1)*8; for (int i=0; i<(int)in.size(); ++i)in_array[i] = in.at(i); memset(in_array + in.size(), ch, 8 - data_rest); for (int i=0; i<len; i += 8) { DES_ecb3_encrypt((DES_cblock *)(in_array + i), (DES_cblock *)(out_array + i), &keyschedc1, &keyschedc2, &keyschedc3, DES_ENCRYPT); } out.assign(out_array, len); return 0; } int main(int argc, char **argv) { // 原始明文 std::string srcText = "test 3DES"; std::string encryptText; std::string encryptHexText; std::string decryptText; std::cout << "=== 原始明文 ===" << std::endl; std::cout << srcText << std::endl; std::cout << "=== 3des加解密 ===" << std::endl; std::string desKey = "wemnsanb1wemnaqnbqpamnaqnbvfdewsxcvbgyhujiuytrfdsedfvnmk"; Des3DesEncrypt(desKey, srcText, encryptText); std::cout << "加密字符: " << std::endl; std::cout << base64Encode(encryptText.c_str(), encryptText.length(), false) << std::endl; //decryptText = des_decrypt(encryptText, desKey); //std::cout << "解密字符: " << std::endl; //std::cout << decryptText << std::endl; return 0; }
执行结果:
=== 原始明文 ===
test 3DES
=== 3des加解密 ===
加密字符:
/XnXVk51IzF+TP1+Xi3Z7g==
AES 是块加密算法,也就是说,每次处理的数据是一块(16 字节、128位),当数据不是 16 字节的倍数时填充,这就是所谓的分组密码(区别于基于比特位的流密码),16 字节是分组长度。AES 共有 ECB、CBC 等多种模式。
// AES示例 #include <iostream> #include <string.h> #include <stdio.h> #include <vector> #include "openssl/aes.h" #include "openssl/evp.h" #include "openssl/bio.h" #include "openssl/buffer.h" using namespace std; std::string base64Encode(const char * input, int length, bool with_new_line) { BIO* bmem = NULL; BIO* b64 = NULL; BUF_MEM* bptr = NULL; b64 = BIO_new(BIO_f_base64()); if(!with_new_line) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char * buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff; } // 加密 void AesEncrypt(const unsigned char *in, unsigned char *out, int length, const unsigned char *key, unsigned char *ivec) { AES_KEY encrypt_key; // 设置加密密钥 if(AES_set_encrypt_key((const unsigned char*)key, 128, &encrypt_key) < 0) { cout << "AES_set_encrypt_key failed" << endl; return ; } AES_cbc_encrypt(in, out, length, &encrypt_key, ivec, AES_ENCRYPT); } // 解密 void AesDecrypt(const unsigned char *in, unsigned char *out, int length, const unsigned char *key, unsigned char *ivec) { AES_KEY decrypt_key; if (AES_set_decrypt_key((const unsigned char*)key, 128, &decrypt_key) < 0) { cout << "AES_set_decrypt_key failed" << endl; return ; } AES_cbc_encrypt(in, out, length, &decrypt_key, ivec, AES_DECRYPT); } int main(int argc, char **argv) { unsigned char key[16] = "123456789012345"; unsigned char ivec[16] = "123456789012345"; unsigned char aes_in[20] = "123456act012345678"; unsigned char aes_out[32]; AesEncrypt(aes_in, aes_out, 20, key, ivec); //加密 cout << "Encrypt result:" <<base64Encode((char*)aes_out, 32, false) << endl; memset(aes_in, 0, 20); memcpy(ivec, "123456789012345", 16); AesDecrypt(aes_out, aes_in, 20, key, ivec); //解密 cout << "Decrypt result:" << aes_in << endl; return 0; }
执行结果:
Encrypt result:zVrnKAdkWqHp4SAvj/8wfhuyVQImEemAqhO0feTzazE=
Decrypt result:123456act012345678
非对称加密算法需要两个密钥来进行加密和解密,分别是公钥和私钥。公钥和私钥成对存在,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密。
算法强度复杂、安全性依赖于算法与密钥。但是由于其算法复杂,使得加密解密速度没有对称加密解密的速度快。
加解密和数字签名验证。
关于数字前面和数字证书,可参考:https://blog.csdn.net/qq_34827674/article/details/119081396
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
RSA的算法涉及三个参数,n、e1、e2。其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。e1和e2是一对相关的值,e1可以任意取。
加密盐也是比较常听到的一个概念,盐就是一个随机字符串用来和我们的加密串拼接后进行加密。加盐主要是为了提供加密字符串的安全性。假如有一个加盐后的加密串,黑客通过一定手段这个加密串,他拿到的明文,并不是我们加密前的字符串,而是加密前的字符串和盐组合的字符串,这样相对来说又增加了字符串的安全性。
// RSA代码示例 #include <iostream> #include <string.h> #include <stdio.h> #include <vector> #include "openssl/rsa.h" #include "openssl/pem.h" #include "openssl/evp.h" #include "openssl/bio.h" #include "openssl/buffer.h" using namespace std; std::string base64Encode(const char * input, int length, bool with_new_line) { BIO* bmem = NULL; BIO* b64 = NULL; BUF_MEM* bptr = NULL; b64 = BIO_new(BIO_f_base64()); if(!with_new_line) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); char * buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff; } #define KEY_LENGTH 2048 // 密钥长度 #define PUB_KEY_FILE "pubkey.pem" // 公钥路径 #define PRI_KEY_FILE "prikey.pem" // 私钥路径 // 函数方法生成密钥对 void generateRSAKey(std::string strKey[2]) { // 公私密钥对 size_t pri_len; size_t pub_len; char *pri_key = NULL; char *pub_key = NULL; // 生成密钥对 RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL); BIO *pri = BIO_new(BIO_s_mem()); BIO *pub = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL); PEM_write_bio_RSAPublicKey(pub, keypair); // 获取长度 pri_len = BIO_pending(pri); pub_len = BIO_pending(pub); // 密钥对读取到字符串 pri_key = (char *)malloc(pri_len + 1); pub_key = (char *)malloc(pub_len + 1); BIO_read(pri, pri_key, pri_len); BIO_read(pub, pub_key, pub_len); pri_key[pri_len] = '\0'; pub_key[pub_len] = '\0'; // 存储密钥对 strKey[0] = pub_key; strKey[1] = pri_key; // 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的) FILE *pubFile = fopen(PUB_KEY_FILE, "w"); if (pubFile == NULL) { //assert(false); return; } fputs(pub_key, pubFile); fclose(pubFile); FILE *priFile = fopen(PRI_KEY_FILE, "w"); if (priFile == NULL) { //assert(false); return; } fputs(pri_key, priFile); fclose(priFile); // 内存释放 RSA_free(keypair); BIO_free_all(pub); BIO_free_all(pri); free(pri_key); free(pub_key); } // 命令行方法生成公私钥对(begin public key/ begin private key) // 找到openssl命令行工具,运行以下 // openssl genrsa -out prikey.pem 1024 // openssl rsa -in privkey.pem - pubout -out pubkey.pem // 公钥加密 std::string rsa_pub_encrypt(const std::string &clearText, const std::string &pubKey) { std::string strRet; RSA *rsa = NULL; BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1); // 此处有三种方法 // 1, 读取内存里生成的密钥对,再从内存生成rsa // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa // 3,直接从读取文件指针生成rsa // RSA* pRSAPublicKey = RSA_new(); rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL); int len = RSA_size(rsa); char *encryptedText = (char *)malloc(len + 1); memset(encryptedText, 0, len + 1); // 加密函数 int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING); if (ret >= 0) strRet = std::string(encryptedText, ret); // 释放内存 free(encryptedText); BIO_free_all(keybio); RSA_free(rsa); return strRet; } // 私钥解密 std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey) { std::string strRet; RSA *rsa = RSA_new(); BIO *keybio; keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1); // 此处有三种方法 // 1, 读取内存里生成的密钥对,再从内存生成rsa // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa // 3,直接从读取文件指针生成rsa rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL); int len = RSA_size(rsa); char *decryptedText = (char *)malloc(len + 1); memset(decryptedText, 0, len + 1); // 解密函数 int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING); if (ret >= 0) strRet = std::string(decryptedText, ret); // 释放内存 free(decryptedText); BIO_free_all(keybio); RSA_free(rsa); return strRet; } int main(int argc, char **argv) { // 原始明文 std::string srcText = "test RSA"; std::string encryptText; std::string encryptHexText; std::string decryptText; std::cout << "=== 原始明文 ===" << std::endl; std::cout << srcText << std::endl; std::cout << "=== rsa加解密 ===" << std::endl; std::string key[2]; generateRSAKey(key); std::cout << "公钥: " << std::endl; std::cout << key[0] << std::endl; std::cout << "私钥: " << std::endl; std::cout << key[1] << std::endl; encryptText = rsa_pub_encrypt(srcText, key[0]); std::cout << "加密字符: " << std::endl; std::cout << base64Encode(encryptText.c_str(), encryptText.length(), false) << std::endl; decryptText = rsa_pri_decrypt(encryptText, key[1]); std::cout << "解密字符: " << std::endl; std::cout << decryptText << std::endl; return 0; }
执行结果:
=== 原始明文 === test RSA === rsa加解密 === 公钥: -----BEGIN RSA PUBLIC KEY----- MIIBCAKCAQEAsWHxQu2SKLA/A2esf5xlDg3wapfisrBJjv2MaYU5D1MK/pkWDYCe 7U5IMKtaDKs3ScRdozId7P1NYlPkjCorwaGe1c48+BCwnEh4YHZfozQ88L7MWNUy cIyzgu5TdI0iWJQn9zyYW5Tl8HIOY2wmHAfZcC1GqgGQANZUPHX7jZWvosuO1BVg AIa6jVNRiAWG3U3LqN2pHOx7HZrghLYW+QQw8HXrJmmeX6hVdToapTcME7cVdHiQ JgwTMdQbLziT6/qTBgdLI2ODpWQ2aYSkxOEuI1zgsezmjl22Q1vGwQLyW15NNmzw MwEs3n8h90HjHdmb9CoLfCtYSAbX/w71EQIBAw== -----END RSA PUBLIC KEY----- 私钥: -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAsWHxQu2SKLA/A2esf5xlDg3wapfisrBJjv2MaYU5D1MK/pkW DYCe7U5IMKtaDKs3ScRdozId7P1NYlPkjCorwaGe1c48+BCwnEh4YHZfozQ88L7M WNUycIyzgu5TdI0iWJQn9zyYW5Tl8HIOY2wmHAfZcC1GqgGQANZUPHX7jZWvosuO 1BVgAIa6jVNRiAWG3U3LqN2pHOx7HZrghLYW+QQw8HXrJmmeX6hVdToapTcME7cV dHiQJgwTMdQbLziT6/qTBgdLI2ODpWQ2aYSkxOEuI1zgsezmjl22Q1vGwQLyW15N NmzwMwEs3n8h90HjHdmb9CoLfCtYSAbX/w71EQIBAwKCAQB2QUuB87bFytSs78hV Eu4JXqBHD+x3IDEJ/l2briYKN1ypu2QJAGnziYV1x5Fdx3oxLZPCIWlIqN5BjUMI HB0rwRSOiX36tcsS2vrq+ZUXeCigfzLl43b1syJXSYz4XhbluBqk0xA9De6gTAmX nW69WpD1c4RxVmAAjuLS+VJeYq49prBFXw3AHjqfZgUYp0vcwGg4DdW1D6/vuhzW fGaHbXOgBCxKt3vLmPB57VKrjUpH8p5u2BUIhqaOv4avLBCAXozr9IGSM43R6/wY /H6fciToiY263vnoYpCRmnl7WN+9/wtf/Tz/DDq5MBl3tmMexBxsAD5HbRnjbZUL qXVDAoGBANlUo38itg2NlVNahGYH48A+etYEAeG+OAerv5oIqU3b4tO/HjFExWil FzERlssm4h+jQasL3LVi3OGYrDVxwrB4rcJAZg3X0KgGPwU60pigb7/t/Y5mwD5w cnb0fxaEyfNYBrztU4yVYgSzDQydVejbtFP9I/Y+cJ9EyFI2vn2XAoGBANDxrgdJ UL3SxA9DtePbJtTTsllQxwbPHOuKRBs6Ui9R/S/BUXdxkPwJK7usv1N9AP0EiXzC V7s2ZTfDCJu2s8qyvv1jsnrwRYbkQzcJN041RjbYkP2y3jFBV2Z0dPoDM69mWP85 HYgfDNAVqe8mWmWT/x1VBbfSlxIuGiY20keXAoGBAJDjF6oXJAkJDjeRrZlal9V+ /I6tVpZ+0AUdKmawcN6SlzfUvsuDLkXDZMthDzIZ7BUXgRyykyOXPeu7HXj2gcr7 HoGARAk6ixqu1K4nNxBq9SqeqQmZ1X71oaSi/2RYhqI6ryieN7MOQVh3Xgho4/CS eDf+F/l+9b+DMDbPKakPAoGBAItLyVow4H6MgrTXzpfnbziNIZDghK80vfJcLWd8 Nso2qMqA4PpLtf1bcn0d1OJTVf4DBlMsOnzO7iUssGfPIoch1KjtIadK2QSYLM9b ejQjhCSQYKkh6XYrj5mi+KaszR+ZkKomE7AUszVjxp9u5u5iqhOOA8/hugwevBl5 4YUPAoGAaDgxWJb12UsZaYclsbeBxJ7gLCxLG3hnWBURuNmImbTuUL3eK3yhD6j6 3g9r0oT9mTkLB+f5r4ODDD7yDOWYZbp4JsyPAFp2gva4IP+twA391FRg0p60roKO AZCQ4dCyvnL6V6CnqTFUVhS9H9I7NCZHjUL+eFTAiL+7eFFPuBs= -----END RSA PRIVATE KEY----- 加密字符: XpcptvI+vqqk34oNyppgQ22faFmilhVk3THl3we+kPPvIsMuvL+n2jYZhpBRmgIe5v8dqm8wul8ZU03L3INNMrjEcdU2P0KQFb5dk0ONe9ySm/B6UsZSJuOzT/+FBlpGK63Q94cRWb4JNp3rzbm+IF+m1lS7GtmYthh0axnhdJasm85U9qmiDDT5YX/8VGbvtygMqtIsVq7ZBDCjor3lc8LZR5/d/oPQ5mXNaA6e9CUuc09mwoRNzWHvCBZJRYarOAIkm4XMFwEGDVWX6ca1gZJt/13vtYPrrKYt7i96Z8ANFwl8kipNczK8GGWskmF0auenZD1v/Rh+kof3YGBotg== 解密字符: test RSA
参考:
常用加密算法:https://blog.csdn.net/tianshan2010/article/details/106170662/
md5(base64):https://blog.csdn.net/w1820020635/article/details/88350680
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。