分享

RSA算法加解密---crypto++库和OpenSSL库

 MikeDoc 2011-03-02

1. OpenSSL库

a、 方式一:

#include<string.h>
#include
<openssl/rsa.h>

#pragma comment(lib,"libeay32.lib")
#pragma comment(lib,"ssleay32.lib")

typedef unsigned
char BYTE;
int main(int argc, char* argv[])
{
    BIGNUM b
={0};
    RSA
* pRsa = RSA_generate_key( 1024 ,RSA_F4,0,0);
//pRsa中包含了N D,你这里自己修改就可以了
    char sz[]="abcdefg";
   
int len = RSA_size( pRsa );
    BYTE
* p = new BYTE[ len ];
    memset(p,
0,len);
    RSA_public_encrypt(
sizeof(sz) , (unsigned char *)sz , p , pRsa ,  RSA_PKCS1_PADDING );
   
char out[1024]={0};
    RSA_private_decrypt( len , p , (unsigned
char *)out , pRsa , RSA_PKCS1_PADDING );
    printf(
"%s\n",out);
    RSA_free( pRsa );
   
return 0;
}

相关链接:http://topic.csdn.net/u/20071228/14/c4dd5ab4-cf45-46c1-8976-29c2ed10a400.html

b、 方式二:使用的RSA算法中的n、e、d

加密:

/*
gcc -o rsa-encrypt rsa-encrypt.c -lcrypto
*/

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

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

int main()
{
    int ret, flen;
     BIGNUM *bnn, *bne, *bnd;
    unsigned char *in = "abc";
    unsigned char *out;

     bnn = BN_new();
     bne = BN_new();
     bnd = BN_new();
     BN_hex2bn(&bnn, MODULUS);
     BN_set_word(bne, PUBLIC_EXPONENT);
     BN_hex2bn(&bnd, PRIVATE_EXPONENT);

     RSA *r = RSA_new();
     r->n = bnn;
     r->e = bne;
     r->d = bnd;
     RSA_print_fp(stdout, r, 5);

     flen = RSA_size(r);// - 11;

     out = (char *)malloc(flen);
     bzero(out, flen);
    //memset(out, 0, flen);


    printf("Begin encrypt...\n");
     ret = RSA_public_encrypt(flen, in, out, r,   RSA_NO_PADDING);
    if (ret < 0)
    {
        printf("Encrypt failed!\n");
        return 1;
    }

    printf("Size:%d\n", ret);
    printf("ClearText:%s\n", in);
    printf("CipherText(Hex):\n");
    int i;
    for (i=0; i<ret; i++)
    {
        printf("0x%02x, ", *out);
         out++;
    }
    printf("\n");

    //free(out);

     RSA_free(r);
    return 0;
}



解密:

/*
gcc -o rsa-decrypt rsa-decrypt.c -lcrypto
*/

#include <openssl/rsa.h>

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

int main()
{
    int ret, flen;
     BIGNUM *bnn, *bne, *bnd;
    unsigned char in[] = {0x51, 0xc2, 0x8d, 0xc6};
    unsigned char *out;

     bnn = BN_new();
     bne = BN_new();
     bnd = BN_new();
     BN_hex2bn(&bnn, MODULUS);
     BN_set_word(bne, PUBLIC_EXPONENT);
     BN_hex2bn(&bnd, PRIVATE_EXPONENT);

     RSA *r = RSA_new();
     r->n = bnn;
     r->e = bne;
     r->d = bnd;
     RSA_print_fp(stdout, r, 5);

     flen = RSA_size(r);
     out = (unsigned char *)malloc(flen);
     bzero(out, flen);

    printf("Begin decrypt...\n");
     ret = RSA_private_decrypt(sizeof(in), in, out, r, RSA_NO_PADDING);
    if (ret < 0)
    {
        printf("Decrypt failed!\n");
        return 1;
    }

    printf("Size:%d\n", ret);
    printf("ClearText:%s\n", out);

    free(out);
     RSA_free(r);
    return 0;
}

 

2. crypto++库

a、 方式一:

 

闲来无事研究了一下RSA算法,发现crypto++这个开源加密库很不错(这里就不介绍了,有兴趣可以上网上找到这方面的资料),不过用起来确实 麻烦,特别是RSA算法,USER GUIDE里的例子程序只支持公钥与私钥都是文件的方式,不支持支接用N,D,E初始化的方式。废话不说,看程序:
//头文件"RsaInterface.h"
#pragma once
//#include "stdafx.h"

#include "rsa.h"
#include "hex.h"
#include "files.h"
#include "rng.h"
#include "default.h"
#include "randpool.h"
#include "ida.h"
#include "base64.h"
#include "des.h"
#include "modes.h"
#include "socketft.h"
#include "wait.h"
#include "factory.h"
#include "whrlpool.h"
#include "validate.h"
#include "osrng.h"
#include <iostream>

USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)

#pragma comment(lib, "cryptlib.lib") // crypto++的库,要在工程中设置其目录,具体做法可以参照网上的介绍资料

class RSAInterface
{
public:

        RSA::PrivateKey m_privateKey;
        RSA::PublicKey m_publicKey;
        Integer n;
        Integer e;
        Integer d;       

public:
        RSAInterface(void);
        ~RSAInterface(void);

        //n,d,e必须是10进制数,当用RSA-TOOL生成N,D,E时Number Base要选10
        RSA::PrivateKey  GenerateRSAPrivateKey(const Integer &n, const Integer &d,const Integer &e);
        RSA::PublicKey   GenerateRSAPublicKey(const Integer &n, const Integer &e);//n,d,e必须是10进制数
        string RSAEncryptString(string plain);
        string RSADecryptString(string cipher);
        bool RSASet_n(Integer &nn);
        bool RSASet_e(Integer &ee);
        bool RSASet_d(Integer &dd);

       
};

//实现文件"RsaInterface.cpp"
#include "stdafx.h"
#include "RsaInterface.h"

RSAInterface::RSAInterface(void)
: n("") //可以在这里直接填入N,D,E值,这样就不用在加密前初始化公钥与私钥了。
, d("")
, e("")
{

        // 初始化公钥和私钥
        m_privateKey=GenerateRSAPrivateKey(n, d, e);
        m_publicKey=GenerateRSAPublicKey(n, e);

}

RSAInterface::~RSAInterface(void)
{
}

RSA::PrivateKey  RSAInterface::GenerateRSAPrivateKey(const Integer &n, const Integer &d, const Integer &e)
{

        InvertibleRSAFunction params;
        params.Initialize(n,e,d);
        RSA::PrivateKey m_privateKey( params );
        return m_privateKey;

}
RSA::PublicKey  RSAInterface::GenerateRSAPublicKey(const Integer &n, const Integer &e)
{
        RSAFunction params;
        params.Initialize(n,e);
        RSA::PublicKey m_publicKey( params );
        return m_publicKey;

}

string RSAInterface::RSAEncryptString(string plain)
{

        AutoSeededRandomPool rng;
        // Encryption

        string cipher;

        RSAES_OAEP_SHA_Encryptor en( m_publicKey );

        StringSource(  plain, true,
                new PK_EncryptorFilter( rng, en,
                new HexEncoder(new StringSink(cipher ))

                ) // PK_EncryptorFilter
                ); // StringSource

        return cipher;
}
string RSAInterface::RSADecryptString(string cipher)
{
        AutoSeededRandomPool rng;

        // Decryption

        string plain;

        RSAES_OAEP_SHA_Decryptor de( m_privateKey );

        StringSource( cipher, true,
                new HexDecoder(new PK_DecryptorFilter( rng, de,
                new StringSink( plain ))
                ) // PK_DecryptorFilter
                ); // StringSource

        return plain;

}

bool RSAInterface::RSASet_n(Integer &nn)
{
        n=nn;
        return TRUE;
}
bool RSAInterface::RSASet_e(Integer &ee)
{
        e=ee;
        return TRUE;
}
bool RSAInterface::RSASet_d(Integer &dd)
{
        d=dd;
        return TRUE;
}
// 用法:
RSAInterface myRSA;
//n,d,e可以用RSATOOLS这个工具生成,不过要注意生成时选基数为10,因为这个库里的N,D,E是10进制的
//如果嫌下面的这个KEY的初始化还麻烦也可以直接在RSAInterface 类的初始化中直接填入N,D,E值,以下两行就可以不调用
myRSA.GenerateRSAPrivateKey(const Integer &n, const Integer &d,const Integer &e);//实际使用时填入实际的N,D,E值
myRSA.GenerateRSAPublicKey(const Integer &n, const Integer &e);//n,d,e必须是10进制数
//加密字符串
string myRSA.RSAEncryptString(string plain);
//解密字符串
string myRSA.RSADecryptString(string cipher);

b、 方式二:

/************************** MyRSA.h ********************************/ 
#ifndef __MYRSA_H__  
#define __MYRSA_H__  
 
#include <string>  
 
#include "files.h"  
#include "filters.h"  
#include "hex.h"  
#include "randpool.h"  
#include "rsa.h"  
 
using namespace std;  
using namespace CryptoPP;  
 
class CMyRSA  
{  
public:  
    CMyRSA(void);  
    virtual ~CMyRSA(void);  
 
    //You must set the KeyLength 512, 1024, 2048 ...  
    void GenerateKey(const unsigned int KeyLength, const char *Seed, RSAES_OAEP_SHA_Decryptor &Priv, RSAES_OAEP_SHA_Encryptor &Pub);  
    void GenerateKey(const unsigned int KeyLength, const char *Seed, string &strPriv, string &strPub);  
      
    //use public key to encrypt  
    void EncryptString(const RSAES_OAEP_SHA_Encryptor &Pub, const char *Seed, const string &Plaintext, string &Ciphertext);  
    void EncryptString(const string &strPub, const char *Seed, const string &Plaintext, string &Ciphertext);  
 
    //use private key to decrypt  
    void DecryptString(const RSAES_OAEP_SHA_Decryptor &Priv, const string &Ciphertext, string &Plaintext);  
    void DecryptString(const string &strPriv, const string &Ciphertext, string &Plaintext);  
 
private:  
    static RandomPool & RNG(void);  
 
private:  
    static RandomPool m_sRandPool;  
};  
 
#endif /* End of __MYRSA_H__ */  
 
 
/************************** MyRSA.cpp ********************************/ 
#include "MyRSA.h"  
 
CMyRSA::CMyRSA()  
{  
 
}  
 
CMyRSA::~CMyRSA(void)  
{  
 
}  
 
void CMyRSA::GenerateKey(const unsigned int KeyLength, const char *Seed, RSAES_OAEP_SHA_Decryptor &Priv, RSAES_OAEP_SHA_Encryptor &Pub)  
{  
    RandomPool RandPool;  
    RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));  
      
    //generate private key  
    Priv = RSAES_OAEP_SHA_Decryptor(RandPool, KeyLength);  
 
    //generate public key using private key  
    Pub = RSAES_OAEP_SHA_Encryptor(Priv);  
}  
 
void CMyRSA::GenerateKey(const unsigned int KeyLength, const char *Seed, string &strPriv, string &strPub)  
{  
    RandomPool RandPool;  
    RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));  
 
    //generate private key  
    RSAES_OAEP_SHA_Decryptor Priv(RandPool, KeyLength);  
    HexEncoder PrivateEncoder(new StringSink(strPriv));//本博客作者加:就为了这句代码整整找了1天!  
    Priv.DEREncode(PrivateEncoder);  
    PrivateEncoder.MessageEnd();                 
 
    //generate public key using private key  
    RSAES_OAEP_SHA_Encryptor Pub(Priv);  
    HexEncoder PublicEncoder(new StringSink(strPub));  
    Pub.DEREncode(PublicEncoder);  
    PublicEncoder.MessageEnd();  
}  
 
void CMyRSA::EncryptString(const RSAES_OAEP_SHA_Encryptor &Pub, const char *Seed, const string &Plaintext, string &Ciphertext)  
{  
    RandomPool RandPool;  
    RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));  
 
    int MaxMsgLength = Pub.FixedMaxPlaintextLength();  
    for (int i = Plaintext.size(), j=0; i > 0; i -= MaxMsgLength, j += MaxMsgLength)  
    {  
        string PartPlaintext = Plaintext.substr(j, MaxMsgLength);  
        string PartCiphertext;  
        StringSource(PartPlaintext, true, new PK_EncryptorFilter(RandPool, Pub, new HexEncoder(new StringSink(PartCiphertext))));  
        Ciphertext += PartCiphertext;                    
    }  
}  
 
void CMyRSA::EncryptString(const string &strPub, const char *Seed, const string &Plaintext, string &Ciphertext)  
{  
    StringSource PublicKey(strPub, true, new HexDecoder);  
    RSAES_OAEP_SHA_Encryptor Pub(PublicKey);  
 
    RandomPool RandPool;  
    RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));  
 
    int MaxMsgLength = Pub.FixedMaxPlaintextLength();  
    for (int i = Plaintext.size(), j=0; i > 0; i -= MaxMsgLength, j += MaxMsgLength)  
    {  
        string PartPlaintext = Plaintext.substr(j, MaxMsgLength);  
        string PartCiphertext;  
        StringSource(PartPlaintext, true, new PK_EncryptorFilter(RandPool, Pub, new HexEncoder(new StringSink(PartCiphertext))));  
        Ciphertext += PartCiphertext;                    
    }  
}  
 
void CMyRSA::DecryptString(const RSAES_OAEP_SHA_Decryptor &Priv, const string &Ciphertext, string &Plaintext)  
{  
    //indicate the ciphertext in hexcode  
    int CiphertextLength = Priv.FixedCiphertextLength() * 2;  
    for (int i = Ciphertext.size(), j=0; i > 0; i -= CiphertextLength, j += CiphertextLength)  
    {  
            string PartCiphertext = Ciphertext.substr(j, CiphertextLength);  
            string PartPlaintext;  
            StringSource(PartCiphertext, true, new HexDecoder(new PK_DecryptorFilter(RNG(), Priv, new StringSink(PartPlaintext))));  
            Plaintext += PartPlaintext;  
    }  
}  
 
void CMyRSA::DecryptString(const string &strPriv, const string &Ciphertext, string &Plaintext)  
{  
    StringSource PrivKey(strPriv, true, new HexDecoder);  
    RSAES_OAEP_SHA_Decryptor Priv(PrivKey);  
      
    //indicate the ciphertext in hexcode  
    int CiphertextLength = Priv.FixedCiphertextLength() * 2;  
    for (int i = Ciphertext.size(), j=0; i > 0; i -= CiphertextLength, j += CiphertextLength)  
    {  
            string PartCiphertext = Ciphertext.substr(j, CiphertextLength);  
            string PartPlaintext;  
            StringSource(PartCiphertext, true, new HexDecoder(new PK_DecryptorFilter(RNG(), Priv, new StringSink(PartPlaintext))));  
            Plaintext += PartPlaintext;  
    }  
}  
 
RandomPool & CMyRSA::RNG(void)  
{  
    return m_sRandPool;  
}  
 
RandomPool CMyRSA::m_sRandPool;  
 
 
/************************** Main.h ********************************/ 
#ifndef __MAIN_H__  
#define __MAIN_H__  
 
 
#endif /* End of __MAIN_H__ */  
 
 
/************************** Main.cpp ********************************/ 
#include <unistd.h>  
 
#include <iostream>  
 
#include "Main.h"  
#include "MyRSA.h"  
 
/***** STATIC VARIABLES *****/ 
static RSAES_OAEP_SHA_Encryptor g_Pub;  
static RSAES_OAEP_SHA_Decryptor g_Priv;  
static string g_strPub;  
static string g_strPriv;  
 
int main(int argc, char *argv[])  
{  
    try 
    {  
        char Seed[1024], Message[1024], MessageSeed[1024];  
        unsigned int KeyLength;  
        CMyRSA MyRSA;  
 
        cout << "Key length in bits: ";  
        cin >> KeyLength;  
 
        cout << "\nRandom Seed: ";  
        ws(cin);  
        cin.getline(Seed, 1024);  
 
        cout << "\nMessage: ";  
        ws(cin);      
        cin.getline(Message, 1024);      
 
        cout << "\nRandom Message Seed: ";  
        ws(cin);  
        cin.getline(MessageSeed, 1024);  
          
        MyRSA.GenerateKey(KeyLength, Seed, g_Priv, g_Pub);  
        //MyRSA.GenerateKey(KeyLength, Seed, g_strPriv, g_strPub);  
 
        //If generate key in RSAES_OAEP_SHA_Encryptor and RSAES_OAEP_SHA_Decryptor, please note four lines below  
        /* 
        cout << "g_strPub = " << g_strPub << endl; 
        cout << endl; 
        cout << "g_strPriv = " << g_strPriv << endl; 
        cout << endl; 
        */ 
          
        string Plaintext(Message);  
        string Ciphertext;  
        MyRSA.EncryptString(g_Pub, MessageSeed, Plaintext, Ciphertext);  
        //MyRSA.EncryptString(g_strPub, MessageSeed, Plaintext, Ciphertext);  
        cout << "\nCiphertext: " << Ciphertext << endl;  
        cout << endl;  
 
        string Decrypted;  
        MyRSA.DecryptString(g_Priv, Ciphertext, Decrypted);  
        //MyRSA.DecryptString(g_strPriv, Ciphertext, Decrypted);  
        cout << "\nDecrypted: " << Decrypted << endl;  
        return 0;  
    }  
    catch(CryptoPP::Exception const &e)  
    {  
        cout << "\nCryptoPP::Exception caught: " << e.what() << endl;  
        return -1;  
    }  
    catch(std::exception const &e)  
    {  
        cout << "\nstd::exception caught: " << e.what() << endl;  
        return -2;  
    }  
    return -3;  
}  

转载链接:http://blog.csdn.net/phker/archive/2009/12/22/5056288.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多