首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

OpenSSL rsa 加密解密解决办法

2013-02-02 
OpenSSLrsa 加密解密问题:用PEM_read_RSAPrivateKey 读取私钥文件总是返回NULL 。但是文件是存在私钥的。刚

OpenSSL rsa 加密解密
问题:用PEM_read_RSAPrivateKey 读取私钥文件总是返回NULL 。但是文件是存在私钥的。刚接触OPenSSL 希望有用过的前辈们提点一二。谢谢!
代码:

//myRsa.h文件

#ifndef MYRSA_H
#define MYRSA_H

#pragma once

#include <memory.h>
#include <string>

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

#define MODULUS "C8FBCF21"
#define PUBLIC_EXPONENT RSA_F4
#define PRIVATE_EXPONENT "97B55D7D"

 #define BUFFSIZE 1024

class myRsa
{
public:
    myRsa();
    ~myRsa();

public:
    RSA * rsa;
    CString StringToEncrypt;
    CString EncryptString;
    CString StringToDecrypt;
    CString DecryptString;

public:
EVP_PKEY* GetPrivateKey(); //获取私钥
EVP_PKEY* GetPublicKey(); //获取公钥
void ProduceKey(); //生成公钥和私钥
    CString RsaEncrypt(CString StrToEncrypt, char *path_key = 0); //加密
    CString RsaDecrypt(CString StrToDecrypt, char *path_key =0); //解密

};

#endif // RSA_H



//myRsa.cpp文件

#include "StdAfx.h"
#include "myRsa.h"

myRsa::myRsa()
{
    this->EncryptString = "";
    this->StringToDecrypt = "";
    this->StringToEncrypt = "";
    this->DecryptString = "";

    this->rsa = 0;
    this->rsa = RSA_new();

ProduceKey();
}

myRsa::~myRsa()
{
    RSA_free(this->rsa);
    this->rsa = 0;
}

CString myRsa::RsaEncrypt(CString StrToEncrypt, char *path_key)
{
unsigned char *p_en;
FILE *file;
int flen;
int rsa_len;

if((file = fopen("G:\\程序\\VC++\\TestOpenSSLRsa\\publicKey.key", "r")) == NULL)
{
perror("open key file error");
return NULL;    
}


if((this->rsa = PEM_read_RSAPublicKey(file, NULL, NULL, NULL)) == NULL)
{
ERR_print_errors_fp(stdout);
return NULL;
}   

char *ba = StrToEncrypt.GetBuffer(0);
   
flen = strlen((char *)ba);
rsa_len = RSA_size(this->rsa);
p_en = (unsigned char *)malloc(rsa_len + 1);
memset(p_en, 0, rsa_len + 1);
if(RSA_public_encrypt(rsa_len, (unsigned char *)ba, (unsigned char*)p_en, this->rsa, RSA_NO_PADDING)<0)
{
return NULL;
}

fclose(file);
return (char *)p_en;
}

CString myRsa::RsaDecrypt(CString StrToDecrypt, char *path_key)
{
     unsigned char *p_de;
     FILE *file;
     int rsa_len;

 if((file = fopen("G:\\程序\\VC++\\TestOpenSSLRsa\\privateKey.key", "r")) == NULL)
 {
         perror("open key file error");


         return NULL;
     }

 /*BIO  * key  =  NULL; 
 key  =  BIO_new(BIO_s_file()); 
 BIO_read_filename(key, "G:\\程序\\VC++\\TestOpenSSLRsa\\privateKey.key" ); 
 this->rsa = PEM_read_bio_RSAPrivateKey(key, NULL, NULL, NULL); 

 if(this->rsa == NULL)
 {
    return NULL;
 }*/   //同样返回NULL

 if((this->rsa = PEM_read_RSAPrivateKey(file, NULL, NULL, NULL)) == NULL)
 {
         ERR_print_errors_fp(stdout);
         return NULL;
     }

 char *ba = StrToDecrypt.GetBuffer(0);

 rsa_len = RSA_size(this->rsa);
     p_de = (unsigned char *)malloc(rsa_len + 1);
     memset(p_de, 0, rsa_len+1);

 if(RSA_private_decrypt(rsa_len, (unsigned char *)ba, (unsigned char*)p_de, this->rsa, RSA_NO_PADDING)<0)
 {
         return NULL;
     }
    
     fclose(file);
     return (char *)p_de;

}


void myRsa::ProduceKey()

this->rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);

if(this->rsa == NULL)
{
//printf("gen rsa error\n");
exit(-1);
}

// 公钥
BIO *bp = BIO_new(BIO_s_file());
if(BIO_write_filename(bp, "G:\\程序\\VC++\\TestOpenSSLRsa\\publicKey.key")<=0)
{
//printf("write error\n");
exit(-1);
}

if(PEM_write_bio_RSAPublicKey(bp, this->rsa)!=1)
{
//printf("write public key error\n");
exit(-1);


BIO_free_all(bp);

char passwd[]="1234";
// 私钥
bp = BIO_new_file("G:\\程序\\VC++\\TestOpenSSLRsa\\privateKey.key", "w+");
if(PEM_write_bio_RSAPrivateKey(bp, this->rsa, EVP_des_ede3(), (unsigned char*)passwd, 4, NULL, NULL)!=1)
{
//printf("write public key error\n");
exit(-1);
}

BIO_free_all(bp); 

}

[解决办法]
不懂,帮你顶一下,我在做onvif的时候有用到,不过gsoap全部搞定了,不用我去关心

热点排行