openssl生成公钥私钥对的方法

在计算机软件开发世界中,编程语言种类极多,数据在各种语言的表现形式可能有所差异,但数据本身的处理可能,或者说本质上是完全一样的;比如数据在某个算法中的运算过程是一样的。在这里,我以加密与解密来作为例子说明。

在C++下,我使用OPENSSL库生成了RSA的公私钥对与DES加密之用的会话密钥,并将这三者及加密结果写入文件以备在Java环境下使用。

在C++程序中,我使用使用公钥来加密了DES的会话密钥,然后在Java下使用私钥来解密会话密钥;在运算结果中,我未做其它方面的码制转换,即按密钥的初始格式DER编码,数学运算结果也是按DER编码来实现。

在Java程序中,我从之前所存储的几个文件中取得密钥与加密结果来做解密。我使用了BC的JCE,即bcprov-jdk14-119.jar,在使用之前,需要先安装此JCE:

假设JDK:jdk1.4\jre\

把BC包放到JRE下的ext:jdk1.4\jre\lib\ext

修改文件jdk1.4\jre\lib\security\java.security:

#

#Listofprovidersandtheirpreferenceorders(seeabove):

#

security.provider.1=sun.security.provider.Sun

security.provider.2=com.sun.net.ssl.internal.ssl.Provider

security.provider.3=com.sun.rsajca.Provider

security.provider.4=com.sun.crypto.provider.SunJCE

security.provider.5=sun.security.jgss.SunProvider

security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider

======================================================================

C++程序源码:

#include

#include

#include

//#define_RSA_KEY_PAIR_GENERATE_//密钥是否要生成只需要在第一次运行时打开此宏

#define_RSA_KEY_PAIR_TOFILE_//密钥对是否要写入文件

#defineMAX_RSA_KEY_LENGTH512//密钥的最大长度是512字节

#definePUBKEY_ENCRYPT

#definePRIKEY_DECRYPT

#pragmacomment(lib,"../lib/libeay32.lib")

staticconstchar*PUBLIC_KEY_FILE="pubkey.key";

staticconstchar*PRIVATE_KEY_FILE="prikey.key";

intRsaKeyPairGen(void)

{

RSA*rsa=NULL;

#ifdef_RSA_KEY_PAIR_GENERATE_

//生成RSA密钥对:

rsa=RSA_new();

rsa=RSA_generate_key(1024,0x10001,NULL,NULL);

#endif

//把密钥对写入文件,以后从文件里读取

#ifdef_RSA_KEY_PAIR_TOFILE_

unsignedcharucPubKey[MAX_RSA_KEY_LENGTH]={0},ucPriKey[MAX_RSA_KEY_LENGTH]={0};

intlen=i2d_RSAPublicKey(rsa,NULL);

unsignedchar*pt=ucPubKey;

len=i2d_RSAPublicKey(rsa,&pt);

FILE*fpubkey=NULL;

fpubkey=fopen(PUBLIC_KEY_FILE,"wb");

if(fpubkey==NULL)

{

cout<<"fopenpubkey.keyfailed!"<<endl;

return0x01;

}

fwrite(ucPubKey,1,len,fpubkey);

fclose(fpubkey);

len=i2d_RSAPrivateKey(rsa,NULL);

unsignedchar*pt2=ucPriKey;

len=i2d_RSAPrivateKey(rsa,&pt2);

FILE*fprikey=NULL;

fprikey=fopen(PRIVATE_KEY_FILE,"wb");

if(fprikey==NULL)

{

cout<<"fopenprikey.keyfailed!"<<endl;

return0x02;

}

fwrite(ucPriKey,1,len,fprikey);

fclose(fprikey);

#endif

if(rsa!=NULL)

{

RSA_free(rsa);

rsa=NULL;

}

return0;

}

//从文件里读取私钥的数据,取得RSA格式的私钥:

intGetPriKey(unsignedchar*pucPriKeyData,unsignedlongKeyDataLen,RSA**priRsa)

{

unsignedchar*Pt=pucPriKeyData;

*priRsa=d2i_RSAPrivateKey(NULL,&Pt,KeyDataLen);

if(priRsa==NULL)

{

cout<<"priRsa==NULL!"<<endl;

return0x22;

}

return0;

}

//取得RSA格式的公钥:

intGetPubKey(unsignedchar*pucPubKeyData,unsignedlongKeyDataLen,RSA**pubRsa)

{

unsignedchar*Pt=pucPubKeyData;

*pubRsa=d2i_RSAPublicKey(NULL,&Pt,KeyDataLen);

if(pubRsa==NULL)

{

cout<<"pubRsa==NULL!"<<endl;

return0x31;

}

return0;

}

//公钥加密会话密钥:

intencSessionKeybyRsaPubKey(RSA*rsa,unsignedchar*ucKey,unsignedlongulKeyLen,

unsignedchar*outData,unsignedlong*pulOutLen)

{

return(*pulOutLen=RSA_public_encrypt(ulKeyLen,ucKey,outData,rsa,1));

}

//私钥解密会话密钥:

intdecSessionKeybyRsaPriKey(RSA*rsa,unsignedchar*InData,unsignedlongulDataLen,

unsignedchar*ucKey,unsignedlong*pulKeyLen)

{

return(*pulKeyLen=RSA_private_decrypt(ulDataLen,InData,ucKey,rsa,1));

}

intmain(intargc,char*argv[])

{

unsignedcharucKey[8]={0x01,0x03,0x99,0x4,\

0x80,0x65,0x34,0x08};

unsignedcharucEncryptedKey[512]={0},ucDecryptedKey[512]={0};

unsignedlongencrypted_len=0,decrypted_len=0;

#ifdef_RSA_KEY_PAIR_GENERATE_

RsaKeyPairGen();

#endif

//取得公钥:

unsignedcharucPubKey[MAX_RSA_KEY_LENGTH]={0};

FILE*fpubkey=NULL;

fpubkey=fopen(PUBLIC_KEY_FILE,"rb");

if(fpubkey==NULL)

{

cout<<"fopenpubkey.keyfailed!"<<endl;

return0x03;

}

fseek(fpubkey,0,SEEK_END);

intlen_PK=ftell(fpubkey);

fseek(fpubkey,0,SEEK_SET);

fread(ucPubKey,1,len_PK,fpubkey);

fclose(fpubkey);

#ifdefPUBKEY_ENCRYPT

RSA*pRsaPubKey=NULL;

pRsaPubKey=RSA_new();

GetPubKey(ucPubKey,len_PK,&pRsaPubKey);

//公钥加密:

encSessionKeybyRsaPubKey(pRsaPubKey,ucKey,sizeof(ucKey),ucEncryptedKey,&encrypted_len);

//writetofile:

FILE*fp=NULL;

fp=fopen("ucKey.data","wb");

fwrite(ucEncryptedKey,1,encrypted_len,fp);

fclose(fp);

if(pRsaPubKey!=NULL)

{

RSA_free(pRsaPubKey);pRsaPubKey=NULL;

}

#endif

//取得私钥:

unsignedcharucPriKey[MAX_RSA_KEY_LENGTH]={0};

FILE*fprikey=NULL;

fprikey=fopen(PRIVATE_KEY_FILE,"rb");

if(fprikey==NULL)

{

cout<<"fopenprikey.keyfailed!"<<endl;

return0x02;

}

fseek(fprikey,0,SEEK_END);

intlen_SK=ftell(fprikey);

fseek(fprikey,0,SEEK_SET);

fread(ucPriKey,1,len_SK,fprikey);

fclose(fprikey);

#ifdefPRIKEY_DECRYPT

RSA*pRsaPriKey=NULL;

pRsaPriKey=RSA_new();

GetPriKey(ucPriKey,len_SK,&pRsaPriKey);

//私钥解密:

FILE*fp1=NULL;

fp1=fopen("ucKey.data","rb");

intlen=ftell(fp1);

fseek(fp1,0,SEEK_SET);

fread(ucPriKey,1,len_SK,fp1);

fclose(fp1);

decSessionKeybyRsaPriKey(pRsaPriKey,ucEncryptedKey,encrypted_len,ucDecryptedKey,&decrypted_len);

if(pRsaPriKey!=NULL)

{

RSA_free(pRsaPriKey);pRsaPriKey=NULL;

}

//数据对比:

if(0==memcmp(ucKey,ucDecryptedKey,decrypted_len))

{

cout<<"OK!"<<endl;

}

else

{

cout<<"FAILED!"<<endl;

}

#endif

return0;

}

======================================================================

Java程序源码:

======================================================================

packagejrsaencrypt;

importjava.io.*;

importjava.security.*;

importjava.security.spec.*;

importjava.security.PublicKey;

importjava.security.PrivateKey;

importjava.security.KeyFactory;

importjavax.crypto.Cipher.*;

/**

*

Title:

*

Description:

*

Copyright:Copyright(c)2005

*

Company:

*@authornotattributable

*@version1.0

*/

publicclassRsaKeyGen{

publicRsaKeyGen(){

}

/**

*生成RSA密钥对

*@return

*/

intgenerateRsaKeyPair(){

//generateanRSAkeypair

try{

KeyPairGeneratorkeyGen=KeyPairGenerator.getInstance("RSA");

keyGen.initialize(1024);

KeyPairpair=keyGen.generateKeyPair();

System.out.println(pair.getPublic().getFormat());

System.out.println(pair.getPublic().getAlgorithm());

System.out.println("\nRSApublicKey:");

byte[]bPubKey=pair.getPublic().getEncoded();

System.out.println(bPubKey.length);

for(inti=0;i<bPubKey.length;i++){

System.out.print(bPubKey[i]+"");

}

System.out.println("\nRSAprivateKey:");

byte[]bPriKey=pair.getPrivate().getEncoded();

System.out.println(bPriKey.length);

for(inti=0;i<bPriKey.length;i++){

System.out.print(bPriKey[i]+"");

}

}

catch(Exceptione){

e.printStackTrace();

}

return0;

}

/**

*从公钥数据取得公钥

*@parambPubKeyInput

*@return

*/

PublicKeygetRsaPubKey(byte[]bPubKeyInput){

byte[]bX509PubKeyHeader={

48,-127,-97,48,13,6,9,42,-122,72,-122,-9,13,1,1,1,5,0,

3,-127,-115,0};

try{

byte[]bPubKey=newbyte[bPubKeyInput.length+bX509PubKeyHeader.length];

System.arraycopy(bX509PubKeyHeader,0,bPubKey,0,

bX509PubKeyHeader.length);

System.arraycopy(bPubKeyInput,0,bPubKey,bX509PubKeyHeader.length,

bPubKeyInput.length);

X509EncodedKeySpecrsaKeySpec=newX509EncodedKeySpec(bPubKey);

KeyFactorykeyFactory=KeyFactory.getInstance("RSA");

rsaPubKey=keyFactory.generatePublic(rsaKeySpec);

}

catch(Exceptione){

e.printStackTrace();

}

returnrsaPubKey;

}

/**

*从私钥数据取得私钥

*@parambPriKeyInput

*@return

*/

PrivateKeygetRsaPriKey(byte[]bPriKeyInput){

byte[]bX509PriKeyHeader={

48,-126,2,117,2,1,0,48,13,6,9,42,

-122,72,-122,-9,13,1,1,1,5,0,4,-126,2,95};

try{

byte[]bPriKey=newbyte[bX509PriKeyHeader.length+bPriKeyInput.length];

System.arraycopy(bX509PriKeyHeader,0,bPriKey,0,

bX509PriKeyHeader.length);

System.arraycopy(bPriKeyInput,0,bPriKey,bX509PriKeyHeader.length,

bPriKeyInput.length);

PKCS8EncodedKeySpecrsaKeySpec=newPKCS8EncodedKeySpec(bPriKey);

KeyFactorykeyFactory=KeyFactory.getInstance("RSA");

rsaPriKey=keyFactory.generatePrivate(rsaKeySpec);

}

catch(Exceptione){

e.printStackTrace();

}

returnrsaPriKey;

}

/**

*从文件里取得数据

*@paramstrFileName

*@parambFBytes

*@return

*/

intgetBytesbyFileName(StringstrFileName,byte[]bFBytes){

intfSize=0;

try{

FileInputStreamfIn=newFileInputStream(strFileName);

fSize=fIn.available();

System.out.print("file'ssize:");

System.out.println(fSize);

fSize=fIn.read(bFBytes);

fIn.close();

}

catch(Exceptione){

e.printStackTrace();

}

returnfSize;

}

/**

*公钥加密

*@parambKey

*@return

*/

byte[]rsaPubKeyEncrypt(byte[]bKey){

try{

//Providerprvd=Security.getProvider("BouncyCastle");

javax.crypto.CipherrsaPKenc=javax.crypto.Cipher.getInstance(

"RSA/ECB/PKCS1Padding");

rsaPKenc.init(javax.crypto.Cipher.ENCRYPT_MODE,rsaPubKey);

bEncryptedData=rsaPKenc.doFinal(bKey);

}

catch(Exceptione){

e.printStackTrace();

}

returnbEncryptedData;

}

/**

*私钥解密

*@parambEncryptedKey

*@return

*/

byte[]rsaPriKeyDecrypt(byte[]bEncryptedKey){

try{

javax.crypto.CipherrsaSKDec=javax.crypto.Cipher.getInstance(

"RSA/ECB/PKCS1Padding");

rsaSKDec.init(javax.crypto.Cipher.DECRYPT_MODE,rsaPriKey);

byte[]bDecrypt=rsaSKDec.doFinal(bEncryptedKey);

//System.out.println("rsadecryptedresult[beforeclean]:");

//for(inti=0;i<bDecrypt.length;i++){

//System.out.print(bDecrypt[i]+"");

//}

//System.out.println();

inti=0;

//for(i=bDecrypt.length;i>1;i--){

//if(bDecrypt[i-1]==0){

//System.out.println("i="+i);

//break;

//}

//}//for

bDecryptedData=newbyte[bDecrypt.length-i];

System.arraycopy(bDecrypt,i,bDecryptedData,0,bDecrypt.length-i);

}

catch(Exceptione){

e.printStackTrace();

}

returnbDecryptedData;

}

publicstaticvoidmain(String[]args){

RsaKeyGenrsaKeyGen1=newRsaKeyGen();

//rsaKeyGen1.generateRsaKeyPair();

//byte[]bPubKey=newbyte[140];

//intlen=rsaKeyGen1.getBytesbyFileName("pubkey.key",bPubKey);

//rsaKeyGen1.getRsaPubKey(bPubKey);

byte[]bPriKey=newbyte[607];

intlen2=rsaKeyGen1.getBytesbyFileName("prikey.key",bPriKey);

rsaKeyGen1.getRsaPriKey(bPriKey);

//byte[]bKey={

//1,2,3,4,5,6,7,8};

////encrypt:

//byte[]bEncKey=rsaKeyGen1.rsaPubKeyEncrypt(bKey);

//System.out.println("rsaencryptedresult:");

//for(inti=0;i<bEncKey.length;i++){

//System.out.print(bEncKey[i]+"");

//}

//System.out.println();

byte[]bEncKey=newbyte[128];

intlen0=rsaKeyGen1.getBytesbyFileName("ucKey.data",bEncKey);

byte[]bDecKey=rsaKeyGen1.rsaPriKeyDecrypt(bEncKey);

System.out.println("rsadecryptedresult:");

for(inti=0;i<bDecKey.length;i++){

System.out.print(bDecKey[i]+"");

}

System.out.println();

}

PublicKeyrsaPubKey;

PrivateKeyrsaPriKey;

byte[]bEncryptedData;

byte[]bDecryptedData;

}

相关推荐