john icon indicating copy to clipboard operation
john copied to clipboard

keystore2john and bks2john should support getting hashes from key-level encryption

Open wdormann opened this issue 6 years ago • 4 comments

Java keystore (JKS) files and Bouncy Castle keystore (BKS) are not encrypted at the container level. Because of this, the keystore password is useful only when a private key uses the same password as the keystore. This is the default, but in no way mandatory.

keystore2.john.py only gets the hash for the container level, but not the private key. So for any JKS file that has a different key password than container password, cracking the password accomplishes nothing. (you can view the keystore contents without needing any password, and you can actually change the keystore-level password without needing to know what it is!).

Steps to reproduce

  1. Make a JKS file with a key password different than the store password. e.g.: keytool -importkeystore -deststorepass password -destkeypass longerpassword -destkeystore mitmproxy.jks -srckeystore mitmproxy-ca.p12 -srcstorepass password
  2. Run keystore2john.py to get a hash for this new jks file
  3. Run john to get the password. It returns "password" as the JKS password
  4. Try to decrypt the private key using this password. e.g. by converting to a new PKCS12: keytool -importkeystore -srckeystore mitmproxy.jks -srcstorepass password -deststoretype pkcs12 -destkeystore mitmproxy-out.p12 -deststorepass password

Note that you will be prompted for the key password, which is "longerpassword". But John doesn't have the ability to get/crack this key-level password.

Note that BKS files are in the same boat. But John is even less useful for BKS-V1 files, as due to a bug in BKS-V1 files, John will find the first password that provides a collision with the only-16-bit HMAC. For this reason, a BKS key file will almost never be crackable with John, because John will stop finding passwords at the first match, which is usually not the actual password for the keys contained within (even if the creator used the same password for the keystore as the keys). The BKS key files themselves don't have the same 16-bit flaw as the keystore, so whatever fix to allow key-level hashes for JKS files should also fix BKS files. Or possibly John could keep running after it finds the first hit when cracking BKS-V1 files, like it appears to do for some other formats.

Attached is a zip of a JKS file with a keystore password of "password" and a key password of "longerpassword", as well as the resulting output from keystore2john.py.

mitmproxy_jks.zip

wdormann avatar Mar 23 '18 14:03 wdormann

@wdormann Thanks for reporting this issue! It has been on my TODO list for a long while now.

kholia avatar Mar 24 '18 04:03 kholia

Also see https://github.com/magnumripper/JohnTheRipper/issues/2725 (Improve JKS cracking support in JtR).

kholia avatar Apr 20 '18 08:04 kholia

Also see https://github.com/kurtbrose/pyjks/blob/master/jks/jks.py for information on the file format and algorithms involved.

kholia avatar May 20 '18 11:05 kholia

any updates on the key level cracking?

frankenstein91 avatar Aug 15 '22 11:08 frankenstein91