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

# List of providers and their preference orders (see above): 

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_//密钥对是否要写入文件 

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

#define PUBKEY_ENCRYPT 
#define PRIKEY_DECRYPT 

#pragma  comment(lib, "../lib/libeay32.lib") 
static const char * PUBLIC_KEY_FILE = "pubkey.key"; 
static const char * PRIVATE_KEY_FILE = "prikey.key"; 

int RsaKeyPairGen(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_ 
unsigned char ucPubKey[MAX_RSA_KEY_LENGTH] = {0}, ucPriKey[MAX_RSA_KEY_LENGTH] = {0}; 
int len = i2d_RSAPublicKey(rsa,NULL); 
unsigned char* pt = ucPubKey; 
len = i2d_RSAPublicKey(rsa, &pt); 

FILE *fpubkey = NULL; 
fpubkey = fopen(PUBLIC_KEY_FILE, "wb"); 
if(fpubkey == NULL) 

  cout << "fopen pubkey.key failed!" << endl; 
  return 0x01; 

fwrite(ucPubKey, 1, len, fpubkey); 
fclose(fpubkey); 

len = i2d_RSAPrivateKey(rsa,NULL); 
unsigned char* pt2 = ucPriKey; 
len = i2d_RSAPrivateKey(rsa,&pt2); 
FILE *fprikey = NULL; 
fprikey = fopen(PRIVATE_KEY_FILE, "wb"); 
if(fprikey == NULL) 

  cout << "fopen prikey.key failed!" << endl; 
  return 0x02; 

fwrite(ucPriKey, 1, len, fprikey); 
fclose(fprikey); 
#endif 

if(rsa != NULL) 

  RSA_free(rsa); 
  rsa = NULL; 

return 0; 


//从文件里读取私钥的数据,取得RSA格式的私钥: 
int GetPriKey(unsigned char *pucPriKeyData, unsigned long KeyDataLen, RSA* *priRsa) 

unsigned char *Pt = pucPriKeyData; 
*priRsa = d2i_RSAPrivateKey(NULL, &Pt, KeyDataLen); 
if(priRsa == NULL) 

  cout << "priRsa == NULL!" << endl; 
  return 0x22; 

return 0; 


//取得RSA格式的公钥: 
int GetPubKey(unsigned char *pucPubKeyData,unsigned long KeyDataLen, RSA* *pubRsa) 

unsigned char *Pt = pucPubKeyData; 
*pubRsa = d2i_RSAPublicKey(NULL, &Pt, KeyDataLen); 
if(pubRsa == NULL) 

  cout << "pubRsa == NULL!" << endl; 
  return 0x31; 

return 0; 


//公钥加密会话密钥: 
int encSessionKeybyRsaPubKey(RSA *rsa, unsigned char *ucKey, unsigned long ulKeyLen, 
        unsigned char *outData, unsigned long *pulOutLen) 

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


//私钥解密会话密钥: 
int decSessionKeybyRsaPriKey(RSA *rsa, unsigned char *InData, unsigned long ulDataLen, 
        unsigned char *ucKey, unsigned long *pulKeyLen) 

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


int main(int argc, char* argv[]) 

unsigned char ucKey[8] = {0x01, 0x03, 0x99, 0x4, \ 
  0x80, 0x65, 0x34, 0x08}; 
unsigned char ucEncryptedKey[512] = {0}, ucDecryptedKey[512] = {0}; 
unsigned long encrypted_len = 0, decrypted_len = 0; 

#ifdef  _RSA_KEY_PAIR_GENERATE_ 
RsaKeyPairGen(); 
#endif 

//取得公钥: 
unsigned char ucPubKey[MAX_RSA_KEY_LENGTH] = {0}; 

FILE *fpubkey = NULL; 
fpubkey = fopen(PUBLIC_KEY_FILE, "rb"); 
if(fpubkey == NULL) 

  cout << "fopen pubkey.key failed!" << endl; 
  return 0x03; 

fseek(fpubkey, 0, SEEK_END); 
int len_PK = ftell(fpubkey); 
fseek(fpubkey, 0, SEEK_SET); 
fread(ucPubKey, 1, len_PK, fpubkey); 
fclose(fpubkey); 

#ifdef  PUBKEY_ENCRYPT 
RSA *pRsaPubKey = NULL; 
pRsaPubKey = RSA_new(); 

GetPubKey(ucPubKey, len_PK, &pRsaPubKey); 
//公钥加密: 
encSessionKeybyRsaPubKey(pRsaPubKey, ucKey, sizeof(ucKey), ucEncryptedKey, &encrypted_len); 
//write to file: 
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 

//取得私钥: 
unsigned char ucPriKey[MAX_RSA_KEY_LENGTH] = {0}; 

FILE *fprikey = NULL; 
fprikey = fopen(PRIVATE_KEY_FILE, "rb"); 
if(fprikey == NULL) 

  cout << "fopen prikey.key failed!" << endl; 
  return 0x02; 

fseek(fprikey, 0, SEEK_END); 
int len_SK = ftell(fprikey); 
fseek(fprikey, 0, SEEK_SET); 
fread(ucPriKey, 1, len_SK, fprikey); 
fclose(fprikey); 

#ifdef PRIKEY_DECRYPT 
RSA *pRsaPriKey = NULL; 
pRsaPriKey = RSA_new(); 

GetPriKey(ucPriKey, len_SK, &pRsaPriKey); 
//私钥解密: 
FILE *fp1 = NULL; 
fp1 = fopen("ucKey.data", "rb"); 
int len = 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 

return 0; 


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

Java程序源码: 

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

package jrsaencrypt; 

import java.io.*; 
import java.security.*; 
import java.security.spec.*; 
import java.security.PublicKey; 
import java.security.PrivateKey; 
import java.security.KeyFactory; 
import javax.crypto.Cipher.*; 

/** 


Title: 


Description: 


Copyright: Copyright (c) 2005 


Company: 

* @author not attributable 
* @version 1.0 
*/ 
public class RsaKeyGen { 

  public RsaKeyGen() { 
  } 
  /** 
   * 生成RSA密钥对 
   * @return 
   */ 
  int generateRsaKeyPair() { 
    //generate an RSA key pair 
    try { 
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); 
      keyGen.initialize(1024); 
      KeyPair pair = keyGen.generateKeyPair(); 
      System.out.println(pair.getPublic().getFormat()); 
      System.out.println(pair.getPublic().getAlgorithm()); 
      System.out.println("\nRSA public Key:"); 
      byte[] bPubKey = pair.getPublic().getEncoded(); 
      System.out.println(bPubKey.length); 
      for (int i = 0; i < bPubKey.length; i++) { 
        System.out.print(bPubKey[i] + " "); 
      } 
      System.out.println("\nRSA private Key:"); 
      byte[] bPriKey = pair.getPrivate().getEncoded(); 
      System.out.println(bPriKey.length); 
      for (int i = 0; i < bPriKey.length; i++) { 
        System.out.print(bPriKey[i] + " "); 
      } 

    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return 0; 
  } 
  /** 
   * 从公钥数据取得公钥 
   * @param bPubKeyInput 
   * @return 
   */ 
  PublicKey getRsaPubKey(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 = new byte[bPubKeyInput.length + bX509PubKeyHeader.length]; 
      System.arraycopy(bX509PubKeyHeader, 0, bPubKey, 0, 
                       bX509PubKeyHeader.length); 
      System.arraycopy(bPubKeyInput, 0, bPubKey, bX509PubKeyHeader.length, 
                       bPubKeyInput.length); 

      X509EncodedKeySpec rsaKeySpec = new X509EncodedKeySpec(bPubKey); 
      KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
      rsaPubKey = keyFactory.generatePublic(rsaKeySpec); 
    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 

    return rsaPubKey; 
  } 

  /** 
   * 从私钥数据取得私钥 
   * @param bPriKeyInput 
   * @return 
   */ 
  PrivateKey getRsaPriKey(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 = new byte[bX509PriKeyHeader.length + bPriKeyInput.length]; 
      System.arraycopy(bX509PriKeyHeader, 0, bPriKey, 0, 
                       bX509PriKeyHeader.length); 
      System.arraycopy(bPriKeyInput, 0, bPriKey, bX509PriKeyHeader.length, 
                       bPriKeyInput.length); 

      PKCS8EncodedKeySpec rsaKeySpec = new PKCS8EncodedKeySpec(bPriKey); 
      KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
      rsaPriKey = keyFactory.generatePrivate(rsaKeySpec); 
    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return rsaPriKey; 
  } 

  /** 
   * 从文件里取得数据 
   * @param strFileName 
   * @param bFBytes 
   * @return 
   */ 
  int getBytesbyFileName(String strFileName, byte[] bFBytes) { 
    int fSize = 0; 
    try { 
      FileInputStream fIn = new FileInputStream(strFileName); 
      fSize = fIn.available(); 
      System.out.print("file's size: "); 
      System.out.println(fSize); 
      fSize = fIn.read(bFBytes); 
      fIn.close(); 
    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return fSize; 
  } 

  /** 
   * 公钥加密 
   * @param bKey 
   * @return 
   */ 
  byte[] rsaPubKeyEncrypt(byte[] bKey) { 
    try { 
//      Provider prvd = Security.getProvider("BouncyCastle"); 
      javax.crypto.Cipher rsaPKenc = javax.crypto.Cipher.getInstance( 
          "RSA/ECB/PKCS1Padding"); 
      rsaPKenc.init(javax.crypto.Cipher.ENCRYPT_MODE, rsaPubKey); 
      bEncryptedData = rsaPKenc.doFinal(bKey); 
    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return bEncryptedData; 
  } 

  /** 
   * 私钥解密 
   * @param bEncryptedKey 
   * @return 
   */ 
  byte[] rsaPriKeyDecrypt(byte[] bEncryptedKey) { 
    try { 
      javax.crypto.Cipher rsaSKDec = javax.crypto.Cipher.getInstance( 
          "RSA/ECB/PKCS1Padding"); 
      rsaSKDec.init(javax.crypto.Cipher.DECRYPT_MODE, rsaPriKey); 
      byte[] bDecrypt = rsaSKDec.doFinal(bEncryptedKey); 
//      System.out.println("rsa decrypted result[before clean]:"); 
//      for (int i = 0; i < bDecrypt.length; i++) { 
//        System.out.print(bDecrypt[i] + " "); 
//      } 
//      System.out.println(); 

      int i = 0; 
//      for (i = bDecrypt.length; i > 1; i--) { 
//        if (bDecrypt[i-1] == 0) { 
//          System.out.println("i=" + i); 
//          break; 
//        } 
//      } //for 
      bDecryptedData = new byte[bDecrypt.length - i]; 
      System.arraycopy(bDecrypt, i, bDecryptedData, 0, bDecrypt.length - i); 
    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return bDecryptedData; 
  } 

  public static void main(String[] args) { 
    RsaKeyGen rsaKeyGen1 = new RsaKeyGen(); 

//    rsaKeyGen1.generateRsaKeyPair(); 

//    byte[] bPubKey = new byte[140]; 
//    int len = rsaKeyGen1.getBytesbyFileName("pubkey.key", bPubKey); 
//    rsaKeyGen1.getRsaPubKey(bPubKey); 

    byte[] bPriKey = new byte[607]; 
    int len2 = 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("rsa encrypted result:"); 
//    for (int i = 0; i < bEncKey.length; i++) { 
//      System.out.print(bEncKey[i] + " "); 
//    } 
//    System.out.println(); 

    byte[] bEncKey = new byte[128]; 
    int len0 = rsaKeyGen1.getBytesbyFileName("ucKey.data", bEncKey); 
    byte[] bDecKey = rsaKeyGen1.rsaPriKeyDecrypt(bEncKey); 
    System.out.println("rsa decrypted result:"); 
    for (int i = 0; i < bDecKey.length; i++) { 
      System.out.print(bDecKey[i] + " "); 
    } 
    System.out.println(); 
  } 

  PublicKey rsaPubKey; 
  PrivateKey rsaPriKey; 
  byte[] bEncryptedData; 
  byte[] bDecryptedData; 
}

openssl生成公钥私钥对 加解密的更多相关文章

  1. .net core中使用openssl的公钥私钥进行加解密

    这篇博文分享的是 C#中使用OpenSSL的公钥加密/私钥解密 一文中的解决方法在 .net core 中的改进.之前的博文针对的是 .NET Framework ,加解密用的是 RSACryptoS ...

  2. .net core 中使用 openssl 公钥私钥进行加解密

    这篇博文分享的是 C#中使用OpenSSL的公钥加密/私钥解密 一文中的解决方法在 .net core 中的改进.之前的博文针对的是 .NET Framework ,加解密用的是 RSACryptoS ...

  3. Java中使用OpenSSL生成公钥私钥进行数据加解密

    当前使用的是Linux系统,已经安装OpenSSL软件包. 一.使用OpenSSL来生成私钥和公钥1.执行命令openssl version -a 验证机器上已经安装openssl $ openssl ...

  4. PHP 生成公钥私钥,加密解密,签名验签

    test_encry.php <?php //创建私钥,公钥 //create_key(); //要加密内容 $str = "test_str"; //加密 $encrypt ...

  5. OpenSSL生成公钥私钥***

    证书标准 X.509 - 这是一种证书标准,主要定义了证书中应该包含哪些内容.其详情可以参考RFC5280,SSL使用的就是这种证书标准. 编码格式 同样的X.509证书,可能有不同的编码格式,目前有 ...

  6. PHP Openssl 生成公钥私钥

    <?php //配置信息 $dn = array( "countryName" => "GB", "stateOrProvinceName ...

  7. 用 openSSL 生成 公钥 私钥

    支付宝app接口需要 RSA加密通讯 https://doc.open.alipay.com/doc2/detail?treeId=58&articleId=103242&docTyp ...

  8. cer, pfx 创建,并且读取公钥/密钥,加解密 (C#程序实现)

    PKI技术(public key infrastructure)里面,cer文件和pfx文件是很常见的.通常cer文件里面保存着公钥以及用户的一些信息,pfx里面则含有私钥和公钥. 用makecert ...

  9. cer, pfx 创建,而且读取公钥/密钥,加解密 (C#程序实现)

    PKI技术(public key infrastructure)里面,cer文件和pfx文件是非经常见的.通常cer文件中面保存着公钥以及用户的一些信息,pfx里面则含有私钥和公钥. 用makecer ...

随机推荐

  1. Ubuntu16.04下Django项目的部署

    起飞前的准备 # 首先在Ubuntu的当前用户zhang下新建data文件夹,然后在data文件夹下新建你的项目目录root@zhang-virtual-machine:/home/zhang/dat ...

  2. ubuntu安装交叉编译工具链

    一.sudo su 切换到root用户权限 二.将arm-linux-gcc-4.3.2.tgz从windows拷贝到Linux  /home/ttt/arm-linux-gcc-4.3.2.tgz ...

  3. Linux下Tun/Tap设备通信原理

    Tun/Tap都是虚拟网卡,没有直接映射到物理网卡,是一种纯软件的实现.Tun是三层虚拟设备,能够处理三层即IP包,Tap是二层设备,能处理链路层网络包如以太网包.使用虚拟网络设备,可以实现隧道,如O ...

  4. 谈谈 T 型人才

    谈谈 T 型人才   昨天的图片发模糊了,正好我把这个话题展开聊一聊吧.这个话题是关于复合型人才的,我把它称作 T 型人才. 「全栈」工程师 前一段时间,「全栈」工程师的概念很火,不过大多数时候,「全 ...

  5. 用python编写的无线AP扫描器

    代码如下: #coding=utf-8 import os import sys import subprocess from scapy.all import * RSN = 48 #管理帧信息元素 ...

  6. TXT文本写入数据库

    load data local infile "D:/abc.txt" into table lee; leedabao.txt内容如下,中间用Tab隔开: 2 yuanpeng ...

  7. 升级svn 到1.7

    sudo yum update sudo yum groupinstall "Development tools" sudo yum groupinstall "Addi ...

  8. 【转】Android IDA 动态调试最完善攻略,跨过各种坑

    前提条件和运行环境一定要写清楚,不然会有很多坑,坑死人. (1)IDA 是最新的7.0版本  (2) JDB 使用Java安装目录下的 (3)系统是win10 使用命令窗口时有很大的差别 (4)手机是 ...

  9. STL algorihtm算法iter_swap(29)

    iter_swap原型: std::iter_swap template <class ForwardIterator1, class ForwardIterator2> void ite ...

  10. SAM4E单片机之旅——11、UART之PDC收发

    使用PDC进行数据的收发能减少CPU的开销.这次就使用PDC进行UART数据的接收与发送,同时,也利用TC也实现了PDC的接收超时. PDC是针对外设的DMA控制器.对比DMA控制器,它更为简便,与相 ...