7

I'm trying to load a private key from file in java. This key is generated by ssh-agent. I'm actually using the code below:

     public PrivateKey getPrivateKeyFromFile() {
    try {
        //String privateKey = readFileAsString(System.getProperty("user.dir")+"/clefs/"+privateKeyName);
        //byte[] encodePrivateKey = privateKey.getBytes();
        File filePrivateKey = new File(System.getProperty("user.dir")+"/clefs/"+privateKeyName);
        FileInputStream fis = new FileInputStream(System.getProperty("user.dir")+"/clefs/"+privateKeyName);
        byte[] encodePrivateKey = new byte[(int) filePrivateKey.length()];
        fis.read(encodePrivateKey);
        fis.close();

        java.security.KeyFactory keyFactory = java.security.KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec privatekeySpec = new PKCS8EncodedKeySpec(encodePrivateKey);
        PrivateKey prikey = (PrivateKey) keyFactory.generatePrivate(privatekeySpec);
        return prikey;

    } catch (NoSuchAlgorithmException ne) {
        ne.printStackTrace();
    } catch (InvalidKeySpecException is) {
        is.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;

}

But it generated this exception:

 java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
at com.nguyenkim.cea.signature.SignChallenge.getPrivateKeyFromFile(SignChallenge.java:53)
at com.nguyenkim.cea.signature.SignChallenge.main(SignChallenge.java:128)
 Caused by: java.security.InvalidKeyException: invalid key format
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:341)
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:367)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75)
at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316)
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213)
... 3 more

Here is the private key:

   -----BEGIN RSA PRIVATE KEY-----
  MIIEowIBAAKCAQEAszReSzBumVb9GR/f3ClgykWE4UsONan1Ywk/H4+Wbi4HpcwB
  8Lm9B+zJ94WdRtD8iQYmbUZFoHwFqTjRPtmQfFXcmxfuI7v64bg0csIw8hz1Af2r
  xo7HBUoVcrTG5k3YrIkjeni/vD9uK6OZ1/lb+/TIvoEp9za577GJxv1omQ6GX7kv
  baMe2GkfpJmrXnA706OEdyi3Ibdcng/V4lbJ9cm+TIBU2jLBqwEukwpL5VNghuQi
  3YfpGhnPDBEnh4h5euFs4DGs4FnCgb+00yCuEgJSPvO5HsTnGbwTtEUnkxjtg8vD
  plD7WenPsyiZqib/rLkNcpfEHKVC6G3QjEuO8QIDAQABAoIBAGliRoFY/fFW4og/
  .............................
  -----END RSA PRIVATE KEY-----

Any suggestions? Thanks.

kimthuat
  • 73
  • 1
  • 1
  • 5
  • are you sure its RSA ? also are you sure that the key is in the right format? – Stephan Apr 26 '13 at 10:10
  • try creating new keys as described in this gist: https://gist.github.com/destan/b708d11bd4f403506d6d5bb5fe6a82c5. Helped me solve this issue. – raksheetbhat May 19 '20 at 07:43

2 Answers2

11

Are you sure its RSA ? also are you sure that the key is in the right format?

If the answer is yes to both questions you can try using bouncycastle lib

EDIT : Try removing these rows from the key:

-----BEGIN RSA PRIVATE KEY-----
.............................
-----END RSA PRIVATE KEY-----

UPDATE : make sure that you private key is in PKCS8 format if not you need to convert it like here

Community
  • 1
  • 1
Stephan
  • 8,000
  • 3
  • 36
  • 42
  • Yes, the key is generated by ssh-agent using the command: ssh-keygen -t rsa -C "my_email@example.com". I'm pretty sure that it is in the right format (see the question edited above). Actually, I know a way to generate a pair of key using bouncy castle, but it will not make a difference here when you always have to load the key generated from file. – kimthuat Apr 26 '13 at 11:29
  • I removed these 2 rows and the result doesn't change. The problem is on this line: PrivateKey prikey = (PrivateKey) keyFactory.generatePrivate(privatekeySpec); I doubt that there is a bug with the PKCS8 encoding – kimthuat Apr 26 '13 at 11:45
  • 1
    Alternatively use the PEM utilities in Bouncy to strip the lines and perform the base64 decoding. No need to do all that yourself. – Maarten Bodewes Apr 03 '15 at 19:33
2

Intstead of removing header and footers from private key file you can use BouncyCastle's Pemreader.

 private PrivateKey getPrivateKeyFromFile(String keyFile) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
    final InputStream inputStream = getClass().getClassLoader().getResourceAsStream(keyFile);
    String privateKeySTr = IOUtils.toString(inputStream, String.valueOf(StandardCharsets.UTF_8));

    PemObject pem = new PemReader(new StringReader(privateKeySTr)).readPemObject();
    byte[] der = pem.getContent();
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(der);
    RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
    return privKey;
}
manishbhadu
  • 144
  • 1
  • 5