感谢支持
我们一直在努力

调用OpenSSL实现RSA加解密和签名操作

RSA公钥可以从证书和公钥文件,RSA私钥可以从私钥文件中提取。OpenSSL使用了一种BIO抽象IO机制读写所用文件,可以打开文件相关联的BIO,通过BIO读写文件内容。

代码示例如下:

// 证书、私钥、公钥都是PEM格式文件

// 编译命令:gcc -o test test_pubkey_pem.c -lcrypto -std=c99

#include <openssl/x509.h>

#include <openssl/pem.h>

#include<stdio.h>

#include<string.h>

 

// 文件路径

char cert_filename[] = “/root/test.crt”;

char pubkey_filename[] = “/root/testpub.pem”;

char prikey_filename[] = “/root/testpri.pem”;

 

int main()

{

 EVP_PKEY *pkey;

 BIO *pubkey_bio;

 BIO *prikey_bio;

 BIO *cert;

 

/************ 从证书中提取公钥 ****************/

// 打开证书文件

cert = BIO_new_file(cert_filename, “r”);

// 读入X509证书

X509 * x_cert = PEM_read_bio_X509(cert, NULL, NULL, NULL);

 BIO_free(cert);

// 提取出密钥EVP_PKEY结构

pkey = X509_get_pubkey(x_cert);

// 提取出RSA结构的公钥

RSA* rsa_from_cert = EVP_PKEY_get1_RSA(pkey);

 X509_free(x_cert);

 EVP_PKEY_free(pkey);

// 打印公钥的值

BIO * print_out=BIO_new(BIO_s_file());

 BIO_set_fp(print_out,stdout,BIO_NOCLOSE);

 RSA_print(print_out, rsa_from_cert, 0);

 

int ret;

/************ 从公钥文件中提取公钥 ****************/

//导入公钥文件

char rsa_in[] = “testing”;

int rsa_inlen = strlen(rsa_in);

 pubkey_bio=BIO_new_file(pubkey_filename,”r”);

 

// 提取出密钥EVP_PKEY结构

pkey=PEM_read_bio_PUBKEY(pubkey_bio, NULL, NULL, NULL);

// 提取出公钥RSA结构

RSA* rsa = EVP_PKEY_get1_RSA(pkey);

 RSA_print(print_out, rsa, 0);

 

/************ 从公钥文件中提取公钥 ****************/

prikey_bio=BIO_new_file(prikey_filename,”r”);

 pkey=PEM_read_bio_PrivateKey(prikey_bio, NULL, NULL, NULL);

 RSA *pri_rsa = EVP_PKEY_get1_RSA(pkey);

 

/*********** 预分配控件 ******************/

// 根据RSA公钥长度分配RSA加密输出空间

int keysize = RSA_size(rsa);

 printf(“keysize:%d\n”, keysize);

unsigned char *rsa_out = OPENSSL_malloc(keysize);

unsigned char *rsa_out_cert = OPENSSL_malloc(keysize);

unsigned char *dec_out = OPENSSL_malloc(keysize);

unsigned char *sign_out = OPENSSL_malloc(keysize);

unsigned char *verify_out = OPENSSL_malloc(keysize);

// 使用RKCS#1填充标准

int pad = RSA_PKCS1_PADDING;

 

/*********** RSA公钥加密 ******************/

int rsa_outlen_cert = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out_cert, rsa_from_cert, pad);

int rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);

 printf(“rsa_outlen is: %d\n”, rsa_outlen);

for(int i=0; i<rsa_outlen; i++){

 printf(“%02x”, rsa_out[i]);

if((i+1)%16 == 0)

 printf(“\n”);

 }

 printf(“\n”);

 printf(“rsa_outlen_cert is: %d\n”, rsa_outlen_cert);

for(int i=0; i<rsa_outlen_cert; i++){

 printf(“%02x”, rsa_out_cert[i]);

if((i+1)%16 == 0)

 printf(“\n”);

 }

 printf(“\n”);

 

/*********** RSA私钥解密 ******************/

 

int dec_len = RSA_private_decrypt(rsa_outlen_cert, rsa_out_cert, dec_out, pri_rsa, pad);

if(!memcmp(rsa_in, dec_out, dec_len)){

 printf(“decrypt success!\n”);

 }else{

 printf(“decrypt fail!\n”);

 }

 printf(“dec_len is %d\n”, dec_len);

 

/*********** RSA私钥签名 *******************/

int sign_len = RSA_private_encrypt(rsa_inlen, rsa_in, sign_out, pri_rsa, pad);

 printf(“sign_len is: %d\n”, sign_len);

for(int i=0; i<sign_len; i++){

 printf(“%02x”, sign_out[i]);

if((i+1)%16 == 0)

 printf(“\n”);

 }

 printf(“\n”);

 

/********** RSA公钥验签 *******************/

int verify_len = RSA_public_decrypt(sign_len, sign_out, verify_out, rsa, pad);

 printf(“verify_len is %d\n”, verify_len);

if(!memcmp(rsa_in, verify_out, verify_len)){

 printf(“verify success!\n”);

 }else{

 printf(“verify fail!\n”);

 }

 

/***********释放变量清理空间 ****************/

OPENSSL_free(rsa_out);

 OPENSSL_free(dec_out);

 OPENSSL_free(rsa_out_cert);

 OPENSSL_free(sign_out);

 OPENSSL_free(verify_out);

 BIO_free(pubkey_bio);

 BIO_free(prikey_bio);

 EVP_PKEY_free(pkey);

 RSA_free(rsa);

 RSA_free(pri_rsa);

 RSA_free(rsa_from_cert);

return 0;

}

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址:https://www.linuxidc.com/Linux/2018-09/154050.htm

赞(0) 打赏
转载请注明出处:服务器评测 » 调用OpenSSL实现RSA加解密和签名操作
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏