调用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;

}

调用OpenSSL实现RSA加解密和签名操作的更多相关文章

  1. RSA加密通信小结(四)--RSA加解密的实际操作与流程小结

    在上一篇文章中,我们已经将密钥的生成方法和流程,归纳总结.而本篇主要是讲如何利用密钥进行加解密. 首先,在上一篇文章中的我们生成了很多密钥,证书等等. 在上述生成的文件中,接收服务端加密报文:pkcs ...

  2. openssl进行RSA加解密(C++)

    密钥对根据RSA的加密机制(自行查找RSA工作原理),通常可以私钥加密-公钥解密(多用于签名),公钥加密-私钥解密(多用于数据传输加密),私钥可以生成公钥. 密钥对生成生成私钥,长度为2048,默认格 ...

  3. openssl在多平台和多语言之间进行RSA加解密注意事项

    首先说一下平台和语言: 系统平台为CentOS6.3,RSA加解密时使用NOPADDING进行填充 1)使用C/C++调用系统自带的openssl 2)Android4.2模拟器,第三方openssl ...

  4. openssl - rsa加解密例程

    原文链接: http://www.cnblogs.com/cswuyg/p/3187462.html openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密.可以使用非对称加 ...

  5. openssl rsa 加解密

    <h4>1.openssl进行rsa加密解密</h4>首先介绍下命令台下openssl工具的简单使用:生成一个密钥:<pre lang="c" esc ...

  6. 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence

    遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...

  7. 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件

    作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...

  8. openssl evp RSA 加密解密

    openssl evp RSA 加密解密 可以直接使用RSA.h 提供的接口 如下测试使用EVP提供的RSA接口 1. EVP提供的RSA 加密解密 主要接口: int EVP_PKEY_encryp ...

  9. RSA 加解密 秘钥对说明

    rsa非对称加密, 加解密需要不同的秘钥,称作一对. rsa加解密分两种,第一:公钥加密私钥解密.第二:私钥加密公钥解密. 需要注意的是,公加私解得到的密文是变化的,而私加公解的得到的密文是固定的. ...

随机推荐

  1. 在mac下设置环境变量

    在mac下设置环境变量   在基于unix/linux的操作系统下进行程序开发,使用环境变量将会方便.通过设置环境变量将可以在任意目录通过输入程序名来执行设定目录下的程序.不需要通过cd将工作目录改变 ...

  2. 2018.09.09 DL24 Day2总结

    今天挂的有点惨…… T1.forging 这道题自己在考试的时候想出来了…… 这题是一个期望递推.我们首先考虑这么一件事,一枚硬币,你抛到正面停止,抛到反面继续抛,问期望抛的次数.是两次.我们假设期望 ...

  3. FastText 分析与实践

    一. 前言 自然语言处理(NLP)是机器学习,人工智能中的一个重要领域.文本表达是 NLP中的基础技术,文本分类则是 NLP 的重要应用.在 2016 年, Facebook Research 开源了 ...

  4. 基于Flink的视频直播案例(上)

    目录 数据产生 Logstash部分 Kafka部分 Flink部分 配置/准备代码 视频核心指标监控 本案例参考自阿里云的视频直播解决方案之视频核心指标监控和视频直播解决方案之直播数字化运营. 基于 ...

  5. attr 和 prop的区别和使用

    一. attr和prop的区别 要想弄清楚attr和prop的区别,就要先搞清楚js中使用DOM方法获取设置属性和使用对象方法获取设置属性的区别. 在javascript中使用DOM方法设置获取属性值 ...

  6. java笔记线程方式1优先级

    * 我们的线程没有设置优先级,肯定有默认优先级. * 那么,默认优先级是多少呢? * 如何获取线程对象的优先级? *   public final int getPriority():返回线程对象的优 ...

  7. 分布式事务(三)mysql对XA协议的支持

    系列目录 分布式事务(一)原理概览 分布式事务(二)JTA规范 分布式事务(三)mysql对XA协议的支持 分布式事务(四)简单样例 分布式事务(五)源码详解 分布式事务(六)总结提高 引子 从Mys ...

  8. golang——strconv包常用函数

    1.func ParseBool(str string) (value bool, err error) 返回字符串表示的bool值.它接受1.0.t.f.T.F.true.false.True.Fa ...

  9. SpringMVC实现Action的两种方式以及与Struts2的区别

    4.程序员写的Action可采用哪两种方式? 第一.实现Controller接口第二.继承自AbstractCommandController接口 5.springmvc与struts2的区别? 第一 ...

  10. WCF 相关配置

    WCF错误:413 Request Entity Too Large 在我们用WCF传输数据的时候,如果启用默认配置,传输的数据量过大,经常会出这个错误. WCF包含服务端与客户端,所以这个错误可能出 ...