RSA 非对称加密笔记

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值