4 Replies Latest reply on Jan 13, 2012 9:46 PM by 910573

    can't use a pfx file with no password in a KeyManagerFactory

      I have a pfx file which contains a private key and a corresponding self-signed certificate. The pfx file itself is not protected by any password. I can't seem to use this pfx file to initialize a KeyManagerFactory for an SSL connection.

      Here's some code which shows what I am trying to do:

      InputStream ksStream = ResourceReader.getResourceAsStream("<pfx-file-location-on-file-system>");
      char[] password = null; //since the pfx file has no password on it
      Keystore keyStore.load(ksStream, password);

      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509", "SunJSSE");
      kmf.init(keystore, password);

      This fails with this exception:

      java.security.UnrecoverableKeyException: Get Key failed: / by zero
           at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:270)
           at java.security.KeyStore.getKey(KeyStore.java:763)
           at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:113)
           at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:48)
           at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:239)
           at jsse.common.JsseSample.createKeyManagerFactory(JsseSample.java:294)
           at jsse.common.JsseSample.createKeyManagerFactory(JsseSample.java:306)
           at jsse.server.Simple.runSample(Simple.java:81)
           at jsse.server.Simple.main(Simple.java:57)
      Caused by: java.lang.ArithmeticException: / by zero
           at com.sun.crypto.provider.PKCS12PBECipherCore.a(DashoA13*..)
           at com.sun.crypto.provider.PKCS12PBECipherCore.a(DashoA13*..)
           at com.sun.crypto.provider.PKCS12PBECipherCore.a(DashoA13*..)
           at com.sun.crypto.provider.PKCS12PBECipherCore.a(DashoA13*..)
           at com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede.engineInit(DashoA13*..)
           at javax.crypto.Cipher.a(DashoA13*..)
           at javax.crypto.Cipher.a(DashoA13*..)
           at javax.crypto.Cipher.init(DashoA13*..)
           at javax.crypto.Cipher.init(DashoA13*..)
           at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineGetKey(PKCS12KeyStore.java:251)
           ... 8 more

      This code works fine if I put a password on the pfx file and then use that password to load the keystore and then use it in the KeyManagerFactory.

      My question is: Why can I not use a pfx file that has not password on it?


      Edited by: 907570 on Jan 12, 2012 1:01 AM

      Edited by: 907570 on Jan 12, 2012 1:18 AM
        • 1. Re: can't use a pfx file with no password in a KeyManagerFactory
          Don't know, but my question is why would you have a private key file without a password? They are rather precious things, they legally constitute the identity of the application. You wouldn't leave your PIN number lying around with your bank card would you? Same thing exactly.
          • 2. Re: can't use a pfx file with no password in a KeyManagerFactory
            I do agree what what you said. Having said that, I am supporting legacy code that was written long ago where someone decided that the way to generate pfx files with private keys in them is to not have a password on them! And then there are always people who want to have the option to not password protect their pfx files because its bothersome to enter the password. :-)

            BTW, since I posted this yesterday, I noticed that BouncyCastle's JCE provider does successfully open a pfx file with not password on it, as long as you set the password to an empty string (""). However, I ideally want to use SUN JCE code and I have no idea why the SunJCE provider can't open these files. I am leaning towards it being a bug in the SunJCE provider code, but am waiting to see if anyone has been able to do what I am trying to do.
            • 3. Re: can't use a pfx file with no password in a KeyManagerFactory
              The actual code used to extract the private key from the keystore is in method sun.security.pkcs12.PKCS12KeyStore.engineGetKey() and the OpenJDK version the private key decryption code fragment is
                             SecretKey skey = getPBEKey(password);
                          Cipher cipher = Cipher.getInstance(algOid.toString());
                          cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
                          byte[] privateKeyInfo = cipher.doFinal(encryptedKey);
                          PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(privateKeyInfo);
              There is no conditional around the decryption so it always tries to generate a PBE key even if no key is provided and then decrypt with that. Of course it could be that a password less pfx file actually does have a default password, there must be an RFC (PKCS12 maybe) that covers this, but I bet that it really does mean that no encryption is done. Assuming that the JCE code in JDK1.7 differs little from this and that having no password really means there is no password then there will be no way in which one can use the Sun provider to access the private key.

              Like you I found that BouncyCastle can handle this situation but if you really cannot work with BouncyCastle then the only other approach I can think of (that does not required a ton of code to be written) is to use OpenSSL to change the pfx password to a default password. If all machines that use your code have OpenSSL installed then this could be done within your Java code using ProcessBuilder. Not very attractive I know but since the JCE cannot handle password less pfx files you are going to have to use a not very attractive solution.

              Edited by: sabre150 on Jan 13, 2012 12:28 PM

              To create a new pfx file with a different password seems to take two OpenSSL commands :-

              openssl pkcs12 -in cert.pfx -out fred
              followed by
              openssl pkcs12 -export -in fred -out fred.pfx
              • 4. Re: can't use a pfx file with no password in a KeyManagerFactory
                Thank you! That answers my question! Really appreciate your time!