『壹』 如何用C语言来使用openssl rsa进行公钥加密,已有公钥和明文

1. 本程序使用2048位密钥对,每次加密时,原始数据的最大长度为245字节,加密后的密文长度为256字节.(采用打PADDING 的加密方式)

2. 如果所加密数据长度大于245字节,请分多次加密,后将密文按顺序存储;解密时,每次读取256字节,进行解密,将解密后的数据依次按顺序存储,即可还原原始数据.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char *my_encrypt(char *str, char *path_key); //加密
char *my_decrypt(char *str, char *path_key); //解密
int main(void)
{
char *source = "i like dancing !!!";
char *ptf_en, *ptf_de;
printf("source is :%s\n", source);
//1.加密
ptf_en = my_encrypt(source, PUBLICKEY);
if (ptf_en == NULL){
return 0;
}else{
printf("ptf_en is :%s\n", ptf_en);
}
//2.解密
ptf_de = my_decrypt(ptf_en, OPENSSLKEY);
if (ptf_de == NULL){
return 0;
}else{
printf("ptf_de is :%s\n", ptf_de);
}
if(ptf_en) free(ptf_en);
if(ptf_de) free(ptf_de);
return 0;
}
//加密
char *my_encrypt(char *str, char *path_key)
{
char *p_en = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
int lenth = 0; //flen为源文件长度, rsa_len为秘钥长度
//1.打开秘钥文件
if((file = fopen(path_key, "rb")) == NULL)
{
perror("fopen() error 111111111 ");
goto End;
}
//2.从公钥中获取 加密的秘钥
if((p_rsa = PEM_read_RSA_PUBKEY(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
lenth = strlen(str);
p_en = (char *)malloc(256);
if(!p_en)
{
perror("malloc() error 2222222222");
goto End;
}
memset(p_en, 0, 256);
//5.对内容进行加密
if(RSA_public_encrypt(lenth, (unsigned char*)str, (unsigned char*)p_en, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error 2222222222");
goto End;
}
End:
//6.释放秘钥空间, 关闭文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_en;
}
//解密
char *my_decrypt(char *str, char *path_key)
{
char *p_de = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
//1.打开秘钥文件
file = fopen(path_key, "rb");
if(!file)
{
perror("fopen() error 22222222222");
goto End;
}
//2.从私钥中获取 解密的秘钥
if((p_rsa = PEM_read_RSAPrivateKey(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
p_de = (char *)malloc(245);
if(!p_de)
{
perror("malloc() error ");
goto End;
}
memset(p_de, 0, 245);
//5.对内容进行加密
if(RSA_private_decrypt(256, (unsigned char*)str, (unsigned char*)p_de, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error ");
goto End;
}
End:
//6.释放秘钥空间, 关闭文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_de;
}

『贰』 如何利用OpenSSL库进行RSA加密和解密

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/engine.h>

intmain(intargc,char*argv[])
{
printf("openssl_testbegin ");
RSA*rsa=NULL;
charoriginstr[]="hello ";//这是我们需要加密的原始数据
//allocateRSAstructure,首先需要申请一个RSA结构题用于存放生成的公私钥,这里rsa就是这个结构体的指针
rsa=RSA_new();
if(rsa==NULL)
{
printf("RSA_newfailed ");
return-1;
}

//generateRSAkeys
BIGNUM*exponent;
exponent=BN_new();//生成RSA公私钥之前需要选择一个奇数(oddnumber)来用于生成公私钥
if(exponent==NULL)
{
printf("BN_newfailed ");
gotoFAIL1;
}
if(0==BN_set_word(exponent,65537))//这里选择奇数65537
{
printf("BN_set_wordfailed ");
gotoFAIL1;
}


//这里molus的长度选择4096,小于1024的molus长度都是不安全的,容易被破解
if(0==RSA_generate_key_ex(rsa,4096,exponent,NULL))
{
printf("RSA_generate_key_exfailed ");
gotoFAIL;
}
char*cipherstr=NULL;
//分配一段空间用于存储加密后的数据,这个空间的大小由RSA_size函数根据rsa算出
cipherstr=malloc(RSA_size(rsa));
if(cipherstr==NULL)
{
printf("malloccipherstrbuffailed ");
gotoFAIL1;
}
//下面是实际的加密过程,最后一个参数paddingtype,有以下几种。
/*
RSA_PKCS1_PADDINGPKCS#1v1.5padding..
RSA_PKCS1_OAEP_PADDING
EME-OAEPasdefinedinPKCS#1v2.0withSHA-1,..
RSA_SSLV23_PADDING
PKCS#1v1.5paddingwithanSSL-.
RSA_NO_PADDING
RawRSAencryption.ntheapplicationcode..
*/
//这里首先用公钥进行加密,选择了RSA_PKCS1_PADDING

if(RSA_size(rsa)!=RSA_public_encrypt(strlen(originstr)+1,originstr,cipherstr,rsa,RSA_PKCS1_PADDING))
{
printf("encryptionfailure ");
gotoFAIL2;
}
printf("theoriginalstringis%s ",originstr);
printf("theencryptedstringis%s ",cipherstr);


//Now,let'
//下面来用私钥解密,首先需要一个buffer用于存储解密后的数据,这个buffer的长度要足够(小于RSA_size(rsa))
//这里分配一个长度为250的字符数组,应该是够用的。
chardecrypted_str[250];
intdecrypted_len;
if(-1=(decrypted_len=RSA_private_decrypt(256,cipherstr,decrypted_str,rsa,RSA_PKCS1_PADDING)))
{
printf("decryptionfailure ");
gotoFAIL2;
}
printf("decryptedstringlengthis%d,decryped_stris%s ",decrypted_len,decrypted_str);
FAIL2:
free(cipherstr);
FAIL1:
BN_free(exponent);
FAIL:
RSA_free(rsa);
return0;
}

以上是源代码,下面使用下面的编译命令在源码所在路径下生成可执行文件
gcc *.c -o openssl_test -lcrypto -ldl -L/usr/local/ssl/lib -I/usr/local/ssl/include
其中,-lcrypto和-ldl是必须的,前者是OpenSSL中的加密算法库,后者是用于成功加载动态库。

『叁』 怎样用公开密钥算法实现数字签名要实现具有保密性的数字签名呢

发送方A用自己的秘密密钥签名并用接受者B的公开密钥加密,B收到报文后用自己的秘密密钥解密,再用A的公开密钥核实签名