2015-04-03 67 views
4

我試圖使用BouncyCastle類來加密和解密密碼。我編寫了測試程序,並以PEM格式和DER格式生成了測試密鑰/證書。我可以將密鑰/證書讀入我的程序,並獲取公鑰並加密一個值。當我嘗試設置解密值時,出現錯誤「org.bouncycastle.asn1.DLSequence無法轉換爲org.bouncycastle.asn1.ASN1Integer」創建AsymmetricKeyParameter時。看來,當我試圖通過執行cert.getEncoded()從證書中提取數據時,它也會引入標題值。我試着只是讀取文件,並刪除BEGIN和END CERTIFCATE行,連同破折號,併網捕獲同樣的錯誤。我曾嘗試使用java.security.cert.Certificate以及下面的代碼使用的X509Certificate。任何幫助將不勝感激。org.bouncycastle.asn1.DLSequence無法轉換爲org.bouncycastle.asn1.ASN1Integer

我可以上傳密鑰文件,這對您會有所幫助,因爲它是我在本地機器上生成的測試密鑰,一旦我有這個工作,它就會被丟棄。

package com.cds.test; 

import java.io.FileInputStream; 
import java.io.InputStream; 
import java.security.Security; 
import java.security.cert.CertificateFactory; 
import java.security.cert.X509Certificate; 

import org.bouncycastle.crypto.AsymmetricBlockCipher; 
import org.bouncycastle.crypto.engines.RSAEngine; 
import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 
import org.bouncycastle.crypto.util.PrivateKeyFactory; 
import org.bouncycastle.crypto.util.PublicKeyFactory; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.util.encoders.Base64; 

public class RSAEncryptDecrypt { 
    public X509Certificate cert = null; 
    // 
    public void readCertificate() throws Exception { 
     Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
     CertificateFactory factory = CertificateFactory.getInstance("X.509", new BouncyCastleProvider()); 
     InputStream fis = new FileInputStream("/opt/temp/keys/openssl_crt.pem"); 
     X509Certificate x509Cert = (X509Certificate) factory.generateCertificate(fis); 
     this.cert = x509Cert; 
     System.out.println("issuer: " + x509Cert.getIssuerX500Principal()); 
    } 
    // 
    public String encrypt(String inputData) throws Exception { 
     Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
     // 
     System.out.println("public key: " + new String(Base64.encode(cert.getPublicKey().getEncoded()))); 
     AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(cert.getPublicKey().getEncoded()); 
     AsymmetricBlockCipher cipher = new RSAEngine(); 
     cipher = new org.bouncycastle.crypto.encodings.PKCS1Encoding(cipher); 
     cipher.init(true, publicKey); 
     // 
     byte[] messageBytes = inputData.getBytes(); 
     byte[] hexEncodedCipher = cipher.processBlock(messageBytes, 0, messageBytes.length); 
     // 
     return new String(Base64.encode(hexEncodedCipher)); 
    } 
    // 
    private String decrypt (String encryptedData) throws Exception { 
     Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
     // 
     byte[] certData = cert.getEncoded(); 
     //certData = Base64.decode(certData); 
     AsymmetricKeyParameter privateKey = PrivateKeyFactory.createKey(cert.getEncoded()); 
     AsymmetricBlockCipher cipher = new RSAEngine(); 
     cipher = new org.bouncycastle.crypto.encodings.PKCS1Encoding(cipher); 
     cipher.init(false, privateKey); 
     // 
     byte[] decoded = Base64.decode(encryptedData.getBytes()); 
     byte[] result = cipher.processBlock(decoded, 0, decoded.length); 
     // 
     return new String(result); 
    } 
    // 
    public static void main(String[] args) throws Exception { 
     String inputData = "This is the message I am trying to encrypt."; 
     String encrypted = null; 
     String decrypted = null; 
     // 
     RSAEncryptDecrypt rsa = new RSAEncryptDecrypt(); 
     // 
     rsa.readCertificate(); 
     System.out.println(" input: " + inputData); 
     encrypted = rsa.encrypt(inputData); 
     System.out.println("encrypted: " + encrypted); 
     decrypted = rsa.decrypt(encrypted); 
     System.out.println("decrypted: " + decrypted); 
    } 
} 

回答

2

證書只包含公鑰,而不包含私鑰。當然,公鑰有一個與之關聯的私鑰,但不保存在證書中。證書是你分發給其他各方的證書。

這可能是因爲您一直在使用Microsoft代碼太多。我提到Microsoft在.NET代碼中的證書類可以在內部包含相關的私鑰,從而使API過於簡化。

所以要解密你將不得不分別讀取你的證書私鑰(使用PKCS8EncodedKeySpec"RSA"KeyFactory)。

另一種選擇是將兩者都放入PKCS#12密鑰存儲區,並使用KeyStore.load將其讀入Java。

+0

不要使用微軟,但也通常不處理加密,所以我不知道不包含私鑰的證書。一旦我讀到你的答案,就會變得更加清晰。我能夠將我的私鑰編碼爲PKCS8格式,並將其讀入我的Java程序中。謝謝你的幫助。 – user1379903 2015-04-06 16:43:29

+1

證書用於分發信任。如果他們包含私鑰,那麼任何接收證書的人也都有權模仿生成密鑰對的人。整個PKI概念將變得相當無用,只有公鑰和沒有私鑰:)很高興你把它修好了。 – 2015-04-06 16:47:30

相關問題