1. 程式人生 > >openssl生成公鑰私鑰對 加解密

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: 

# 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++) { 

相關推薦

使用openssl生成PEM格式及ECDSA簽名

一、生成金鑰與讀取的過程     /* 生成公鑰 */     RSA* rsa = RSA_generate_key( 1024, RSA_F4, NULL, NULL);     BIO *bp = BIO_new( BIO_s_file() );     BIO_

openssl生成 解密

在計算機軟體開發世界中,程式語言種類極多,資料在各種語言的表現形式可能有所差異,但資料本身的處理可能,或者說本質上是完全一樣的;比如資料在某個演算法中的運算過程是一樣的。在這裡,我以加密與解密來作為例子說明。        在C++下,我使用OPENSSL庫生成了RSA的公

Java中使用OpenSSL生成的RSA公私資料進行解密

Java基於OpenSSL的公私鑰對資料進行加解密 使用OpenSSL來生成私鑰和公鑰 RSA加密解密工具類 簽名及校驗類 測試類 使用OpenSSL來生成私鑰和公鑰

openssl 生成(包含16進位制

1. 生成原始 RSA私鑰檔案 rsa_private_key.pem openssl genrsa -out rsa_private_key.pem 1024 2. 將原始 RSA私鑰轉換為 pkcs8格式,JAVA需要使用的私鑰需要經過 PKCS8 編碼 openssl pkcs8 -top

mac自帶的openssl 生成(包括java,iOS端各平臺支援的證書轉換)

1.使用終端進入到制定目錄下 2.執行命令:openssl 3.生成一個1024位的私鑰:genrsa -out rsa_private_key.pem 1024 4.利用私鑰生成JAVA支援的PKC

RSA-演變過程、原理、特點(解密及簽名)及生成

本篇是iOS逆向開發總結的第一篇文章,是關於iOS密碼學的相關技術分析和總結,希望對大家有所幫助,如果有錯誤地方歡迎指正。 一、前言 密碼學的歷史追溯到2000年前,相傳古羅馬凱撒大帝為了防止敵方截獲情報,用密碼傳送情報。凱撒大帝的做法比較簡單,通過對二十幾個羅馬字母表建立一張對應的表格,這樣如果不知道密碼,

Windows下生成 以及 配置 Filezilla中的 SFTP的

href gpo .html 公鑰私鑰 www. googl ssh -s HA Win下需要使用到 PuTTYgen.exe來生成公鑰私鑰,可以參考youtube的這篇文章: 為 SFTP 保管箱生成 Secure Shell (SSH) 密鑰對 PuTTYgen.

支付寶支付接入(安全基礎 - 生成

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

java RSA 生成

/** * 引進的包都是Java自帶的jar包 * 祕鑰相關包 * base64 編解碼 * 這裡只用到了編碼 */ import java.security.Key; import java.security.KeyPair; import java.security.KeyPair

C# RSA加密、解密簽、驗籤、支援JAVA格式、PEM格式、.NET格式 -變態模式【支援加密,解密】(二)

RSA變態模式:【私鑰加密,公鑰解密】 一般這種寫法都是JAVA弄的。.NET原生不支援。為啥,我也不清楚,大概是因為安全性問題吧,畢竟公鑰是人人都可是持有的。私鑰只有自己擁有。 簽名一直都是【私鑰加簽、公鑰驗籤】只為證明該訊息是你發出來的。 這裡使用了BouncyC

[email protected]通過Eclipse生成SSH keys RSA

       由於我使用的系統是windows,所以不支援ssh-keygen命令沒法自動生成,雖然有專業的ssh-keygen生成工具,但是懶得去下載了,直接用Eclipse比較方便,這裡就講Eclipse生成SSH keys生成RSA公鑰私鑰的方法。 1.安裝好Git工

ubuntu git生成ssh key ()配置GitLab

Git是分散式的程式碼管理工具,遠端的程式碼管理是基於SSH的,所以要使用遠端的Git則需要SSH的配置。 github的SSH配置如下: 一 、 設定Git的user name和email: git config --global user.name "xx"   

php 生成

<?php //http://www.lampol-blog.com/detail/aid/ZDk5MmFNZ2pJL1pROW5QZU9KZ2FWdVlFTDVHRnRmZm4rNDMzSFlHNg%3D%3D 各種祕鑰生成的教程 //生成金鑰 $opensslCon

C# RSA加密、解密簽、驗籤、支援JAVA格式、PEM格式、.NET格式、一般模式【支援加密,解密】(一)

2017-12-04日更新:增加支援微信支付。程式碼註釋中//☆☆☆☆.NET 4.6以後特有☆☆☆☆的別用,那個不對。 RSA非對稱加密。簡明扼要吧,直說乾貨。(在此特別感謝下貳進位制,提供JAVA版的公鑰私鑰) C#RSA加簽解籤加密比較常見,一般遇到的問題是非.NET

利用Python Crypto生成RSA

# -*- coding: utf-8 -*- from Crypto import Random from Crypto.PublicKey import RSA print "generate private key and pulic key" # 參考 C:\

如何用java RSA生成生成(非對稱加密)

言簡意賅,直接見程式碼:package com; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.K

openssl從PFX匯出

從pfx提取金鑰資訊,並轉換為key格式(pfx使用pkcs12模式補足) 1、提取金鑰對(如果pfx證書已加密,會提示輸入密碼。)        openssl pkcs12 -in 1.pfx -nocerts -nodes -out 1.key 2、從金鑰對提取私鑰

Java中使用OpenSSL生成的RSA公私進行資料解密

RSA是什麼:RSA公鑰加密演算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國麻省理工學院)開發的。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密演算法,它能夠抵抗到目前為止已知的所有密碼攻擊,已被ISO推薦為公

SecureRandom生成“強隨機數”用於生成RSA*/*window和linux下不一致的問題

1.先說下問題: 由於我們的服務部署環境是兩臺伺服器,在服務啟動時生成RSA金鑰對。這有一個問題:當兩臺機器分別啟動時,生成了不同的金鑰對。而當客戶端需要用到RSA加解密的時候,連結可能會被負載到另一臺機器上,造成解密失敗,丟擲異常。 2.看下之前的程式碼(

生成git

cd ~/.ssh 如果能進入到.ssh檔案目錄下 ,則證明,之前生成過.ssh祕鑰,可以直接使用裡面的祕鑰。 如果不能進入到.ssh檔案目錄下,則: 檢測下自己之前有沒有配置:git con