2015-04-06 120 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);