2011-07-02 31 views
25

當嘗試使用方法寒冷的解析錯誤,而不是一個序列

public PrivateKey getPrivateKey() 
     throws NoSuchAlgorithmException, 
     InvalidKeySpecException, IOException { 

    final InputStream inputStream = getClass().getClassLoader() 
        .getResourceAsStream("privatekey"); 
    byte[] privKeyBytes = null; 
    try { 
     privKeyBytes = IOUtils.toByteArray(inputStream); 
    } catch (final IOException exception) { 
     LOGGER.error("", exception); 
     IOUtils.closeQuietly(inputStream); 
    } 

    LOGGER.debug("privKeyBytes: {}", privKeyBytes); 

    String BEGIN = "-----BEGIN RSA PRIVATE KEY-----"; 
    String END = "-----END RSA PRIVATE KEY-----"; 
    String str = new String(privKeyBytes); 
    if (str.contains(BEGIN) && str.contains(END)) { 
     str = str.substring(BEGIN.length(), str.lastIndexOf(END)); 
    } 

    KeyFactory fac = KeyFactory.getInstance("RSA"); 
    EncodedKeySpec privKeySpec = 
      new PKCS8EncodedKeySpec(Base64.decode(str.getBytes())); 
    return fac.generatePrivate(privKeySpec); 
} 

我得到的異常

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:200) ~[na:1.6.0_23] 
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:342) ~[na:1.6.0_23] 

在fac.generatePrivate來讀取文件中的RSA私鑰(privKeySpec)呼叫。

這個錯誤是什麼意思?

感謝

德米特里

回答

37

這意味着你的鑰匙是不是在PKCS#8格式。最簡單的方法是使用openssl pkcs8 -topk8 <...other options...>命令將密鑰轉換一次。或者,您可以使用Bouncycastle lightweight APIPEMReader類。

+20

謝謝,它的工作。這裏的命令是:openssl pkcs8 -topk8 -nocrypt -in myrsakey.pem -out myrsakey_pcks8 –

32

我有這個相同的問題,密鑰的格式不是實際的問題。
我不得不這樣做才能擺脫這一例外的是調用

java.security.Security.addProvider(
     new org.bouncycastle.jce.provider.BouncyCastleProvider() 
); 


和一切工作

+0

這個解決方案確實有效。謝謝。 – user1919346

+0

這是解決方案!有用! – Denny

+0

解決方案的作品,但它背後的理由是什麼? – user1918858

-1

對於我來說,我缺少的公共密鑰OID。我必須糾正使用幫助從這裏iOS的一面:http://blog.wingsofhermes.org/?p=42

而且,我的公鑰沒有被鑄造成RSAPublicKey,標準的工作就好了:

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes); 
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec); 
+1

op正在談論PrivateKey – lznt

4

你必須從您的私鑰製作您的PCKS8文件!私鑰文件的

private.pem =>名稱

的OpenSSL genrsa -out private.pem 1024

public_key.pem =>公共密鑰文件的名稱

OpenSSL的RSA -in私人。 pem -pubout -outform PEM -out public_key.pem

private_key.pem => PCKS8格式的私鑰名稱!你可以閱讀這種格式在java中

OpenSSL的PKCS8 -topk8 -inform PEM -in private.pem退房手續private_key.pem -nocrypt

+1

這是我的問題 - 該文件是使用'genrsa'生成的,該文件創建了PKCS#1格式(這是OP加載的格式,可以通過'BEGIN RSA PRIVATE KEY'標題看到) ,而PKCS#8是不同的格式(由於不同的頭文件:'BEGIN PRIVATE KEY',可以檢測到PEM編碼)。我的密鑰生成器現在看起來像這樣:'openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out private.pem' – Guss

+0

你有類似的EC私鑰生成密鑰嗎? –