2010-04-16 71 views
13

Tôi có khóa riêng được lưu trữ trong tệp ở định dạng DER PKCS8 và được bảo vệ bằng mật khẩu. Cách dễ nhất để đọc nó là gì?Cách đọc mật mã được mã hóa bằng java?

Đây là mã tôi sử dụng để nạp mã hóa một:

InputStream in = new FileInputStream(privateKeyFilename); 
byte[] privateKeydata = new byte[in.available()]; 
in.read(privateKeydata); 
in.close(); 
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA"); 
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata); 
PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec); 

Nó hoạt động tốt cho các phím không được mã hóa với các đặc điểm kỹ thuật tương tự. Nhân tiện, tôi đang sử dụng BouncyCastle.

tôi có thể xem private key này sử dụng sau lệnh openssl

openssl pkcs8 -in ./privatekey.key -inform DER -passin pass:thisismypass 

Xin vui lòng, Help !!!

Tôi đã đăng một số giải pháp trong câu trả lời của riêng mình cho chủ đề này. Nhưng tôi giữ cho câu hỏi chưa được trả lời trong trường hợp ai cũng có thể giúp làm cho nó hoạt động mà không cần thêm thư viện, chỉ BouncyCastle.

Trả lời

7

Tôi đã tìm ra giải pháp! Có lẽ không phải như vậy tao nhã của nó, nhưng ... Ở đây tôi sẽ gửi hai giải pháp:

  1. Prefferable, nhưng không phải làm việc
  2. Làm việc một, nhưng cần thêm thư viện

Đầu tiên :

Tôi đã tìm thấy một loại giải pháp here, nhưng nó ném ngoại lệ. Giải pháp:

import java.io.*; 
import java.security.*; 
import java.security.interfaces.RSAPrivateCrtKey; 
import java.security.interfaces.RSAPublicKey; 
import java.security.spec.*; 

import javax.crypto.*; 
import javax.crypto.spec.*; 

/* 
* This class demonstrates how to import an encrypted RSA private key as 
* generated by openssl. The input file is presumed to be in DER 
* format. 
*/ 
public class ImportEncryptedPrivateKey 
{ 
    public static byte[] readPK8FromFile(String fileName) throws IOException 
    { 
     File f = new File(fileName); 
     DataInputStream dis = new DataInputStream(new FileInputStream(f)); 
     byte[] theData = new byte[(int) f.length()]; 
     dis.readFully(theData); 
     return theData; 
    } 

    public static void main(String[] args) throws IOException, 
      NoSuchAlgorithmException, NoSuchPaddingException, 
      InvalidKeySpecException, InvalidKeyException, 
      InvalidAlgorithmParameterException 
    { 
     byte[] encryptedPKInfo = readPK8FromFile("rsapriv.pk8"); 
     EncryptedPrivateKeyInfo ePKInfo = new EncryptedPrivateKeyInfo(
       encryptedPKInfo); 
     char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; 
     Cipher cipher = Cipher.getInstance(ePKInfo.getAlgName()); 
     PBEKeySpec pbeKeySpec = new PBEKeySpec(password); 
     // Now create the Key from the PBEKeySpec 
     SecretKeyFactory skFac = SecretKeyFactory.getInstance(ePKInfo 
       .getAlgName()); 
     Key pbeKey = skFac.generateSecret(pbeKeySpec); 
     // Extract the iteration count and the salt 
     AlgorithmParameters algParams = ePKInfo.getAlgParameters(); 
     cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams); 
     // Decrypt the encryped private key into a PKCS8EncodedKeySpec 
     KeySpec pkcs8KeySpec = ePKInfo.getKeySpec(cipher); 
     // Now retrieve the RSA Public and private keys by using an 
     // RSA keyfactory. 
     KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA"); 
     // First get the private key 
     RSAPrivateCrtKey rsaPriv = (RSAPrivateCrtKey) rsaKeyFac.generatePrivate(pkcs8KeySpec); 
     // Now derive the RSA public key from the private key 
     RSAPublicKeySpec rsaPubKeySpec = new RSAPublicKeySpec(rsaPriv.getModulus(), rsaPriv.getPublicExponent()); 
     RSAPublicKey rsaPubKey = (RSAPublicKey) rsaKeyFac.generatePublic(rsaPubKeySpec); 
    } 

} 

Và ngoại lệ của tôi:

Exception in thread "main" java.security.NoSuchAlgorithmException: No such algorithm: 1.2.840.113549.1.5.13 

Second:

Và sau đây http://juliusdavies.ca/commons-ssl/pkcs8.html này, bạn có thể đọc về thứ hai, giải pháp làm việc

+0

+1 cho not-yet-commons-ssl. Bạn thậm chí không cần Lâu đài Bouncy. – Thilo

+1

Đối với giải pháp thứ hai. Bạn có thể dán mã ở đây không? Tôi không thể mở liên kết đó. Bạn đã sử dụng thư viện nào? – BRabbit27

+0

Điều này thực sự làm việc cho tôi. –

1

Đây là của tôi mã và nó hoạt động :)

File f = new File(keyFile); 
FileInputStream fis = new FileInputStream(f); 
DataInputStream dis = new DataInputStream(fis); 
byte[] keyBytes = new byte[(int)f.length()]; 
dis.readFully(keyBytes); 
dis.close(); 
EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(keyBytes); 
Cipher cipher = Cipher.getInstance(encryptPKInfo.getAlgName()); 
PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray()); 
SecretKeyFactory secFac = SecretKeyFactory.getInstance(encryptPKInfo.getAlgName()); 
Key pbeKey = secFac.generateSecret(pbeKeySpec); 
AlgorithmParameters algParams = encryptPKInfo.getAlgParameters(); 
cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams); 
KeySpec pkcs8KeySpec = encryptPKInfo.getKeySpec(cipher); 
KeyFactory kf = KeyFactory.getInstance("RSA"); 
return kf.generatePrivate(pkcs8KeySpec); 
+1

Chỉ với JDK (không có Lâu đài Bouncy) tôi nhận được "Không thể tìm thấy bất kỳ nhà cung cấp nào hỗ trợ 1.2.840.113549.1.5.13" (đây là id cho PBEWithMD5AndDES). – Thilo

+1

Bạn đã quản lý để đọc khóa riêng với chỉ java API? – BRabbit27

Các vấn đề liên quan