2015-04-06 85 views
0

使用ClassLoader.class加載密鑰時出錯,爲什麼?爲什麼加載文件時無效的RSA私鑰?

單元測試路徑= 「/..../resource/..../key.der

版部署路徑= ClassLoader.getResource方法(AESKeyPath);

(aESKeyPath =」 key.der 「)

private void loadKey(final String AESKeyPath, final String privateKeyFileDerPath) { 

    Properties prop = new Properties(); 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    InputStream input = classLoader.getResourceAsStream("foo.properties"); 
    prop.load(input); 
    final String classpath = prop.getProperty("test.foo"); 

    File aESKeyFile = null; 
    File privateKeyFile = null; 

    // My version deployed using the if. 
    if (classpath.equals("local")) { 
     URL aesKeyPath = classLoader.getResource(AESKeyPath); 
     if (aesKeyPath != null) { 
      aESKeyFile = new File(aesKeyPath.toURI()); 
     } 

     URL privateKeyURL = classLoader.getResource(privateKeyFileDerPath); 
     if (privateKeyURL != null) { 
      privateKeyFile = new File(privateKeyURL.toURI()); 
     } 

    // The tests used the else 
    } else { 
     aESKeyFile = new File(AESKeyPath); 
     privateKeyFile = new File(privateKeyFileDerPath); 
    } 

    byte[] encodedKey = new byte[(int) privateKeyFile.length()]; 
    new FileInputStream(privateKeyFile).read(encodedKey); 

    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    PrivateKey pk = kf.generatePrivate(privateKeySpec); <---- Error 

    pkCipher.init(Cipher.DECRYPT_MODE, pk); 
    aesKey = new byte[AES_Key_Size/8]; 
    CipherInputStream is = new CipherInputStream(new FileInputStream(AESKeyFile), pkCipher); 
    is.read(aesKey); 
    aeskeySpec = new SecretKeySpec(aesKey, "AES"); 
} 

我的單元測試都通過了,但是當我部署和我加載使用「的ClassLoader的文件時,它給了我這個錯誤:

Caused by: java.security.InvalidKeyException: Invalid RSA private key 
at sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:206) ~[na:1.8.0_40] 
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:342) ~[na:1.8.0_40] 
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356) ~[na:1.8.0_40] 
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91) ~[na:1.8.0_40] 
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) ~[na:1.8.0_40] 
at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316) ~[na:1.8.0_40] 
at  sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213) ~ [na:1.8.0_40] 
    ... 92 common frames omitted 
Caused by: java.io.IOException: DER input, Integer tag error 
at sun.security.util.DerInputStream.getBigInteger(DerInputStream.java:180) ~[na:1.8.0_40] 
at  sun.security.rsa.RSAPrivateCrtKeyImpl.getBigInteger(RSAPrivateCrtKeyImpl.java:214) ~[na:1.8.0_40] 
at  sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:198 ) ~[na:1.8.0_40] 

我比較前10個字節並且相等。最後也是一樣的大小。

我生成密鑰使用以下命令:

openssl genrsa -out private.pem 2048 
openssl pkcs8 -topk8 -in private.pem -outform DER -out private.der -nocrypt 
openssl rsa -in private.pem -pubout -outform DER -out public.der 

回答

0

我的問題是Maven的。 Maven編碼我的密鑰。我解決了在pom.xml中爲資源添加過濾器的問題。我更改我的代碼。

<resources> 
     <resource> 
      <directory>src/main/resources/foo</directory> 
      <filtering>true</filtering> 
      <excludes> 
       <exclude>**/key/*</exclude> 
      </excludes> 
     </resource> 
     <resource> 
      <directory>src/main/resources/foo/key</directory> 
     </resource> 
    </resources> 

String keyDerPath = getClass().getResource(privateKeyFileDerPath).getFile(); 
String AESKeyPathResource = getClass().getResource(AESKeyPath).getFile(); 
aESKeyFile = new File(AESKeyPathResource); 
privateKeyFile = new File(keyDerPath);