1、产生密钥
2、传递公钥
3、用户用公钥加密
4、传递密文
5、服务器用私钥解密
6、初始化完成
#include <iostream>
#include <fstream>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
extern "C"
{
#include <openssl/applink.c>
};
#define DATA_BUFF_LENTH 1024
#define RSA_BIT 1024
using namespace std;
typedef ios_base::openmode _Ios_Openmode;
class File
{
public:
File(string strFilePath):m_strFilePath(strFilePath){};
~File(){};
bool open(_Ios_Openmode opreator);
void close();
void read(char* buff,int length);
private:
fstream m_file;
string m_strFilePath;
};
bool File::open(_Ios_Openmode opreator)
{
m_file.open(m_strFilePath.c_str(),opreator);
if (m_file.fail())
{
cout<<"open file failure!"<<endl;
return false;
}
return true;
}
void File::close()
{
m_file.close();
}
void File::read(char* buff,int length)
{
m_file.read(buff,length);
}
class RSAKey
{
public:
RSAKey(int rsabit,int bignum);
~RSAKey();
void UsePrivateRSAKeyDecode(char* dsc,char* src);
void UsePublicRSAKeyEncode(char* dsc,char* src);
void printPublicKey();
void printPrivateKey();
void exportPrivateKey(string fileName);
void exportPublicKey(string fileName);
/*
We can also output the key into an encrypted PEM file.
And the APIs is easy to use.
PEM_write_bio_RSAPrivateKey
PEM_write_bio_RSAPublicKey
PEM_read_bio_RSAPrivateKey
PEM_read_bio_RSAPublicKey
*/
void importPrivateKey(string fileName);
void importPublicKey(string fileName);
private:
BIGNUM* m_bigNum;
RSA* m_rsa;
int m_rsa_bit;
RSA* m_pubKey;
RSA* m_privateKey;
};
RSAKey::RSAKey(int rsabit,int bignum)
{
int r;
m_rsa_bit = rsabit;
m_rsa = RSA_new();
m_pubKey = RSA_new();
m_privateKey = RSA_new();
m_bigNum = BN_new();
BN_set_word(m_bigNum,bignum);
r = RSA_generate_key_ex(m_rsa, m_rsa_bit, m_bigNum, NULL);
if (r != 0) {
printf("RSA_generate_key_ex error\n");
}
}
RSAKey::~RSAKey()
{
RSA_free(m_rsa);
RSA_free(m_pubKey);
RSA_free(m_privateKey);
BN_free(m_bigNum);
}
void RSAKey::UsePrivateRSAKeyDecode(char* dsc,char* src)
{
int rsa_len = RSA_size(m_privateKey);
int len = RSA_private_decrypt(rsa_len,(unsigned char *)src,(unsigned char*)dsc,m_privateKey,RSA_NO_PADDING);
if (len < rsa_len) {
return;
}
}
void RSAKey::UsePublicRSAKeyEncode(char* dsc,char* src)
{
int rsa_len = RSA_size(m_pubKey);
int len = RSA_public_encrypt(rsa_len, (unsigned char *)src,(unsigned char*)dsc,m_pubKey, RSA_NO_PADDING);
if (len < rsa_len) {
return;
}
}
void RSAKey::printPublicKey()
{
RSA_print_fp(stdout,m_pubKey,11);
}
void RSAKey::printPrivateKey()
{
RSA_print_fp(stdout,m_privateKey,11);
}
void RSAKey::exportPrivateKey(string fileName)
{
if (1) {
BIO *out;
//long BIO_get_mem_data(BIO *b, char **pp);
//BIO_set_mem_buf(BIO *b, BUF_MEM *bm, int c);
//BIO_get_mem_ptr(BIO *b, BUF_MEM **pp);
out = BIO_new(BIO_s_mem()); //BIO_s_file()
if (out) {
int r = PEM_write_bio_RSAPrivateKey(out, m_rsa,NULL, NULL, 0, NULL,NULL);
if (r) {
char * data;
long len;
if (0) {
//int read = BIO_nread0(out, &data);
len = BIO_get_mem_data(out, &data);
}
else {
BUF_MEM *mem;
int rr = BIO_get_mem_ptr(out, &mem);
len = mem->length;
data = mem->data;
}
FILE *ifile;
ifile = fopen(fileName.c_str(),"wb");
if (ifile) {
fwrite(data, 1, len, ifile);
fclose(ifile);
}
BIO_free(out);
}
}
}
else {
FILE *ifile;
ifile = fopen(fileName.c_str(),"wb");
if (ifile) {
PEM_write_RSAPrivateKey(ifile,m_rsa, NULL, NULL, 0, NULL, NULL);
fclose(ifile);
}
}
}
void RSAKey::exportPublicKey(string fileName)
{
FILE *ifile;
ifile = fopen(fileName.c_str(),"wb");
if (ifile) {
PEM_write_RSAPublicKey(ifile,m_rsa);
fclose(ifile);
}
}
void RSAKey::importPrivateKey(string fileName)
{
FILE *ifile;
ifile = fopen(fileName.c_str(),"rb");
if (0) {
m_privateKey = PEM_read_RSAPrivateKey(ifile, NULL, NULL, NULL);
}
else {
char * key;
int key_len, readlen, r;
r = fseek(ifile, 0, SEEK_END);
key_len = ftell(ifile);
key = (char *)malloc(key_len + 1);
fseek(ifile, 0, SEEK_SET);
readlen = fread(key, key_len, 1, ifile);
key[key_len] = '\0';
BIO *b = BIO_new_mem_buf((void *)key, key_len);
if (b) {
m_privateKey = PEM_read_bio_RSAPrivateKey(b, NULL, NULL, NULL);
BIO_free(b);
}
}
fclose(ifile);
}
//importPublicKey
//BIO *bufio;
//RSA *rsa
// bufio = BIO_new_mem_buf((void*)pem_key_buffer, pem_key_buffer_len);
//PEM_read_bio_RSAPublicKey(bufio, &rsa, 0, NULL);
void RSAKey::importPublicKey(string fileName)
{
FILE *ifile;
ifile = fopen(fileName.c_str(),"rb");
m_pubKey = PEM_read_RSAPublicKey(ifile,NULL,NULL,NULL);
fclose(ifile);
}
int main(int argc,char *argv[])
{
RSAKey rsa(RSA_BIT,RSA_F4);
rsa.exportPrivateKey("private.key");
rsa.exportPublicKey("public.key");
rsa.importPublicKey("public.key");
rsa.importPrivateKey("private.key");
rsa.printPrivateKey();
rsa.printPublicKey();
char DataBuff[DATA_BUFF_LENTH];
if (argc > 1) {
string strFilePath = argv[1];
File ifile(strFilePath.c_str());
ifile.open(ios::in);
ifile.read(DataBuff,DATA_BUFF_LENTH);
ifile.close();
cout<<"-----------------------------------"<<endl;
cout<<"source :"<<DataBuff<<endl;
cout<<"-----------------------------------"<<endl;
}
else {
for(size_t i = 0; i < DATA_BUFF_LENTH; i++) {
DataBuff[i] = 'A' + char(i % 26);
}
}
char enData[DATA_BUFF_LENTH];
rsa.UsePublicRSAKeyEncode(enData,DataBuff);
cout<<"-----------------------------------"<<endl;
cout<<"encode :"<<enData<<endl;
cout<<"-----------------------------------"<<endl;
char deData[DATA_BUFF_LENTH];
rsa.UsePrivateRSAKeyDecode(deData,enData);
cout<<"-----------------------------------"<<endl;
cout<<"decode :"<<deData<<endl;
cout<<"-----------------------------------"<<endl;
return 0;
}