C C++使用openssl进行摘要和加密解密(md5, sha256, des, rsa)_c++ openssl sha256

94 阅读4分钟

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。 img img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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);

}

// ---- des对称加解密 ---- //
// 加密 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 < 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 < 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;

}

// ---- rsa非对称加解密 ---- //
#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 = "this is an example";

std::string encryptText;
std::string encryptHexText;
std::string decryptText;

std::cout << "=== 原始明文 ===" << std::endl;
std::cout << srcText << std::endl;

// md5  
std::cout << "=== md5哈希 ===" << std::endl;
md5(srcText, encryptText, encryptHexText);
std::cout << "摘要字符: " << encryptText << std::endl;
std::cout << "摘要串: " << encryptHexText << std::endl;

// sha256  
std::cout << "=== sha256哈希 ===" << std::endl;
sha256(srcText, encryptText, encryptHexText);
std::cout << "摘要字符: " << encryptText << std::endl;
std::cout << "摘要串: " << encryptHexText << std::endl;

// des  
std::cout << "=== des加解密 ===" << std::endl;
std::string desKey = "12345";
encryptText = des_encrypt(srcText, desKey);
std::cout << "加密字符: " << std::endl;
std::cout << encryptText << std::endl;
decryptText = des_decrypt(encryptText, desKey);
std::cout << "解密字符: " << std::endl;
std::cout << decryptText << std::endl;

// rsa  
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 << encryptText << std::endl;
decryptText = rsa_pri_decrypt(encryptText, key[1]);
std::cout << "解密字符: " << std::endl;
std::cout << decryptText << std::endl;

system("pause");
return 0;

}


  
 运行结果


 


 



=== 原始明文 === this is an example

=== md5哈希 === 摘要字符: 乵驥!範 摘要串: 9202816dabaaf34bb106a10421b9a0d0 === sha256哈希 === 摘要字符: 訪X5衽鄁媫j/醢?17?P?4膡zD 摘要串: d44c035835f1c5e0668b7d186a2ff5b0 === des加解密 === 加密字符: ?/灲取鮋t8:夽U錺?说 解密字符: this is an example

=== rsa加解密 === 公钥: -----BEGIN RSA PUBLIC KEY----- MIIBCAKCAQEA59WESdYbPsD6cYATooC4ebClTpvbTsu3X29Ha0g31kW3AmLR2zLj hMvdWjUhhVuM7xBoh3Ufoyj4jTGHVhunFfbzxNrt1Nb64N95bZH8e9u6LjJYqh4e sNoFknG+McjoSLNqGW9Yd8ejKH1Ju6C9SBUcC43XbB3XdC2matgV1zTsKhqjuywm gVN9DZdo2TlZkqsvOHC23rbQ+lP09rpQJ/RI4NQSnCUBqQxErCN85trcWRj1zyJA WaBZSvKh7J5RJcrC2ByMDmL7jrDDZl7YEolyW93SSc4xTE9Dr20OXznXNDsfQc9r RQHBri8Aqsu4WW3tHSBRmjW5kxFMxS4qxwIBAw== -----END RSA PUBLIC KEY-----

私钥: -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA59WESdYbPsD6cYATooC4ebClTpvbTsu3X29Ha0g31kW3AmLR 2zLjhMvdWjUhhVuM7xBoh3Ufoyj4jTGHVhunFfbzxNrt1Nb64N95bZH8e9u6LjJY qh4esNoFknG+McjoSLNqGW9Yd8ejKH1Ju6C9SBUcC43XbB3XdC2matgV1zTsKhqj uywmgVN9DZdo2TlZkqsvOHC23rbQ+lP09rpQJ/RI4NQSnCUBqQxErCN85trcWRj1 zyJAWaBZSvKh7J5RJcrC2ByMDmL7jrDDZl7YEolyW93SSc4xTE9Dr20OXznXNDsf Qc9rRQHBri8Aqsu4WW3tHSBRmjW5kxFMxS4qxwIBAwKCAQEAmo5YMTlnfytRoQAN FwB6+8sY3xKSNIfPlPTaR4V6jtkkrEHhPMyXrd0+PCNrrj0In2BFr6NqbMX7CMuv jr0aDqSigzyejeSnQJT7nmFS/T0myXblxr6/IJFZDEvUITCa2yJGu5+QT9psxajb 0mso2ri9XQk6SBPk+B5u8eVj5Myt4tqpWL0DEEDzwfhihs+uEGM7g6bPvQBI4JXu 8uxfSRUkpyZ5s1koEhqj+RCguksPzSWO/Ut2Sd60iOUMRhya2aEbAyRTtfhsXja3 4NMWjXorJ0SRkryM1iLJvVWkhkcr2vShH9rm9qz16BkrkI9/9Yx++GNNr6VU/p/+ Waa8CwKBgQD4m0ryXi6rCqazdCICGoZJGzaljApOZ1rWOiotM9TekaYE7tZ2NDAT eytiCzxvs4/+1Jt5XzdGJ035VJKSai/n2ZzAq1YYtVHy5CG2olmeFtwaIWU18m2s RjHQf/FiscVB4XdKrHjh3gLgSB8MWMDg/krisxT86HNyp1UE2jZv+QKBgQDuuoez V+H23ktb9oDS9HuLXt+wZuww29uNb0jhVoLiqK6M90Pl2u8yErjsq04cG9pF0MUl 8/nIw4RRKQh9GUOBBbxZqA/1yBxmHTz48siYJ3YXf5HB+0WxxOlEk3s05AnTilTi 5Y4u9Ptwieoy+TOXatBL9XZgKkpHbcxKZH2gvwKBgQClvNyhlB8cscR3osFWvFmG EiRuXVw0ROc5fBweIo3ptm6t9I75eCAM/MeWsihKd7VUjbz7lM+EGjP7jbcMRsqa

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。 img img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!