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
|