摘自:https://wenku.csdn.net/answer/7c7f06c9f8bb466fb48f47bae5aaf99d
摘自:https://www.dandelioncloud.cn/article/details/1498198300963708930
// RsaUtil.c
#include <string> using namespace std; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/sha.h> #include "Base64Util.h" #define KEY_LENGTH 2048 #define PUB_EXP 65537 static string hex_2_string(unsigned char *data, unsigned int data_len) { string str = ""; size_t malloc_len = 2 * data_len + 1; char *tmp_str = (char *)calloc(1, malloc_len); if (NULL == tmp_str) { return ""; } for (unsigned int index = 0; index < data_len; index++) { snprintf(tmp_str + strlen(tmp_str), malloc_len - strlen(tmp_str) - 1, "%02x", data[index]); } str = tmp_str; free(tmp_str); return str; } // 加载公钥 static RSA *load_publicKey(string path_public_key) { FILE *fp = fopen(path_public_key.c_str(), "r"); if (NULL == fp) { printf("Failed to load public key\n"); return NULL; } RSA *rsa_pub = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL); fclose(fp); return rsa_pub; } // 加载私钥 static RSA *load_privateKey(string path_private_key) { FILE *fp = fopen(path_private_key.c_str(), "r"); if (NULL == fp) { printf("Failed to load private key\n"); return NULL; } RSA *rsa_priv = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); fclose(fp); printf("RSA_size=%d\r\n", RSA_size(rsa_priv)); return rsa_priv; } static string __rsa_sign(RSA *private_key, const unsigned char *data, size_t data_len) { unsigned char *signature = NULL; unsigned int signature_length = 0; string out_signature = ""; printf("=========================================================\n"); printf("__rsa_sign data=%s, len=%lu\n", data, data_len); signature_length = RSA_size(private_key); printf("__rsa_sign signature_length=%d\n", signature_length); signature = (unsigned char *)malloc(signature_length); // 计算哈希值 signature_length = RSA_size(private_key); if (1 != RSA_sign(NID_sha256, data, data_len, signature, &signature_length, private_key)) { printf("Failed to generate RSA signature.\n"); return ""; } printf("__rsa_sign signature_length=%d|\n%s\n", signature_length, hex_2_string(signature, signature_length).c_str()); out_signature = base64_encode(signature, signature_length); free(signature); printf("=========================================================\n\n\n"); return out_signature; } static int __rsa_verify(RSA *public_key, const unsigned char *data, size_t data_len, string signature_base64) { unsigned char *signature = NULL; int signature_length = 0; int ret = 0; printf("=========================================================\n"); signature_length = RSA_size(public_key); printf("rsa_verify() signature_length=%d|%lu\n", signature_length, signature_base64.length()); ret = base64_decode(signature_base64, &signature, &signature_length); if (0 != ret) { printf("base64_decode() failed.\n"); return -1; } printf("rsa_verify() signature_length=%d|%lu|\n%s\n", signature_length, signature_base64.length(), hex_2_string(signature, signature_length).c_str()); if (1 != RSA_verify(NID_sha256, data, data_len, signature, signature_length, public_key)) { printf("RSA signature verification failed.\n"); return -1; } printf("RSA signature verification succeeded.\n"); free(signature); printf("=========================================================\n\n\n"); return 0; } string rsa_sign(string path_private_key, const unsigned char *data, size_t data_len) { RSA *private_key = NULL; string out_signature = ""; private_key = load_privateKey(path_private_key); out_signature = __rsa_sign(private_key, data, data_len); RSA_free(private_key); return out_signature; } int rsa_verify(string path_public_key, const unsigned char *data, size_t data_len, string signature_base64) { int ret = 0; RSA *public_key = NULL; public_key = load_publicKey(path_public_key); ret = __rsa_verify(public_key, data, data_len, signature_base64); RSA_free(public_key); return ret; } #if 1 int main() { string sig = ""; string path_public_key = "/root/test/81/lanxin_public.pem"; string path_private_key = "/root/test/81/lanxin_private.pem"; string data = "This is a test message."; int ret = 0; //RSA *rsa = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL); RSA *private_key = load_privateKey(path_private_key); RSA *public_key = load_publicKey(path_public_key); sig = __rsa_sign(private_key, (const unsigned char*)data.c_str(), data.length()); if (sig.length() <= 0) { printf("RSA_sign Failed.\n"); return -1; } printf("sig=%s|\n", sig.c_str()); ret = __rsa_verify(public_key, (const unsigned char*)data.c_str(), data.length(), sig); if (0 != ret) { printf("rsa_verify Failed.\n"); return -1; } return 0; } #endif
// Base64Util.c #include <string> using namespace std; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/bio.h> #include <openssl/evp.h> #include "Base64Util.h" /***************************************************************** Base64编码 参数 : data, 输入参数, 输入数据 data_len, 输入参数, 输入数据长度 return : 长度>0, 成功, 返回 base64 字符串 长度=0, 失败 *****************************************************************/ string base64_encode(const unsigned char *data, int data_len) { BIO *bio = NULL; BIO *b64 = NULL; char *buffer = NULL; int buf_len = 0; if (NULL == data || 0 >= data_len) { return ""; } // 创建Base64编码的BIO b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 去掉所有换行符 bio = BIO_new(BIO_s_mem()); bio = BIO_push(b64, bio); // 写入数据并刷新BIO BIO_write(bio, data, data_len); (void)BIO_flush(bio); // 读取Base64编码后的数据 buf_len = BIO_get_mem_data(bio, &buffer); if (0 <= buf_len) { buffer[buf_len] = '\0'; } string base64_str = (NULL == buffer) ? "" : buffer; // 清理资源 BIO_free_all(bio); // 内部已经 释放buffer return base64_str; } /***************************************************************** Base64解码 参数 : base64_str, 输入参数, base64 字符串 output, 输出参数, 输出数据(请调用者自行free) out_len, 输出参数, 输出数据长度 return : 0, 成功 -1, 失败 *****************************************************************/ int base64_decode(string base64_str, unsigned char **output, int *out_len) { BIO *bio = NULL; BIO *b64 = NULL; char *buffer = NULL; int buf_len = 0; int decoded_len = 0; if (NULL == output || NULL == out_len) { return -1; } // 创建Base64解码的BIO b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 没有换行符 bio = BIO_new_mem_buf(base64_str.c_str(), base64_str.length()); bio = BIO_push(b64, bio); // 读取Base64解码后的数据 buf_len = base64_str.length() * 3 / 4; buffer = (char *)calloc(1, buf_len + 1); decoded_len = BIO_read(b64, buffer, base64_str.length()); if (0 <= decoded_len) { buffer[decoded_len] = '\0'; } *output = (unsigned char *)buffer; *out_len = decoded_len; //printf("decoded_len=%d, buf_len=%d, buffer=%s\r\n", decoded_len, buf_len, buffer); // 清理资源 BIO_free_all(bio); return 0; } #if 0 // 主函数测试Base64编码和解码函数 int main() { const char *str = "Hello, World!我爱你"; string base64_str = ""; unsigned char *output = NULL; int out_len = 0; int ret = 0; base64_str = base64_encode((const unsigned char *)str, strlen(str)); ret = base64_decode(base64_str, &output, &out_len); printf("base64=%s\r\n", base64_str.c_str()); printf("ret=%d, out_len=%d, str=%s\r\n", ret, out_len, output); free(output); return 0; } #endif
g++ Base64Util.c RsaUtil.c -lcrypto -g -Wall ; ./a.out