3
$\begingroup$

Suppose:

  • We are using an application that stores sensitive private key information in a standard Java PKCS #12 keystore.
  • Users are expected to provide an overall store password and also a password for each key in the store.

ASSUMING:

  • The user chooses reasonable passwords that are not trivial to guess (empty, own name, "password" etc.) but are also not extremely strong. Let's say 40 bits of entropy.
  • Attackers obtain access to the keystore .pfx file (as stored on disk)
  • Attackers are UNABLE to obtain one or both of the passwords
  • Attackers are sophisticated, have significant compute power etc.

Are the private keys likely to be safe? If not, how could you improve the protection?

$\endgroup$
1
  • $\begingroup$ Note Java keytool does not support key password(s) different from the store password for PCKS12 (it does for JKS which is broken by design, and JCEKS which is nonstandard -- and BCFKS if you use Bouncy, as Swashbuckler notes). If you write your own tools the API does, but the resulting PKCS12 is not interoperable with anything else I know of, if that matters to you. $\endgroup$ Commented Aug 7 at 23:10

2 Answers 2

2
$\begingroup$

Let's assume Java 21 here, as it is a long term support version.

There are some issues with the passwords:

  • the default amount of iterations for the password-based key derivation function 2, i.e. PBKDF2, is 1000, which was the default very long ago;
  • there are no methods of protecting the password when entered from console;
  • there is no indication of password strength, other than requiring a minimum amount of 6 characters, which is of course not enough to be secure.

This basically means that any password used is hard to enter securely, while also making it easy to enter an altogether insecure password. Note that this is password based encryption (PBE), so attackers are able to crack the store using parallel processes having direct access to the data in the file. Basically you need to enter a password that has the strength of a symmetric key to have any kind of security, and this won't change much even if the number of iterations is set to e.g. 1,000,000. Using a password manager with at least a 16 character fully randomized password if you want to rely on the confidentiality.


In earlier Java versions (which I haven't all tested) they also used older algorithms:

  • they are using 3DES to encrypt the private keys (not sure if it was 2 or 3 key 3DES, but both should not be used anymore);
  • the 40-bit RC2 algorithms is used to encrypt the certificates, while the RC2 algorithm has been known to be broken for some time;

Certificates are not as sensitive as private keys of course, but they may still contain e.g. personal information which you might not want to leak, even if they are usually considered "public".

There are also some good things with newly generated key stores:

  • they use SHA-256 for PBKDF2 but also for HMAC to provide authentication / integration;
  • the newer key stores use AES-256 in CBC mode for providing confidentiality.

Using a hardware key store is currently one of the more logical options, or having a separate key store.

You can have a look at the inner construction of a new PKCS#12 / PFX key store here

$\endgroup$
3
  • $\begingroup$ gotta go, will try and expand later, there are other issues such as using the PBKDF2 two times for key store & private key access. $\endgroup$
    – Maarten Bodewes
    Commented Aug 7 at 16:13
  • $\begingroup$ Traditionally -- until about 2019 -- PKCS12 encrypted certbag not just with RC2 but 40-bit RC2, easily bruteforcible back in the 1990s even without any algorithm weakness (like the 40-bit RC4 and 1DES 'export' suites in then-SSL). OTOH certs are usually published in clear, including to adversaries, so there isn't really any benefit encrypting them in the PKCS12. To be clear it's recent Java that makes the difference, not a new keystore as such; a PKCS12 created today with 8u291 is still 3DES RC2-40 SHA1. $\endgroup$ Commented Aug 8 at 0:03
  • $\begingroup$ Thanks this is very useful. Yes we can assume JDK 21+ $\endgroup$
    – mikera
    Commented Aug 8 at 17:40
0
$\begingroup$

A secret with 40 bits of entropy is not secure, it can be brute forced. NIST currently wants a minimum of 112 bits of entropy for security.

In addition, my notes show that PKCS#12 uses RC2, which is not secure even with passwords that have that good entropy. You might consider using Bouncy Castle BCFKS format which is much more secure as it uses AES 256 and SHA 512. That of course, requires using Bouncy Castle.

$\endgroup$
3
  • 2
    $\begingroup$ Basically no human generated password will have 112 bits of security. That's why they use PBKDF2 with a work factor / iteration count. That adds about 20 bits of security if used correctly, but at the moment the 1000 count is stuck at ~10 bits of security. PKCS#12 may use RC2, but new key stores generated uses keytool use AES/CBC, see my answer. Your notes may need an update :) $\endgroup$
    – Maarten Bodewes
    Commented Aug 7 at 20:49
  • $\begingroup$ Oh, I don't agree with that. Off the characters I can easily type on my keyboard I can get 112 bits with 18 characters. That's a longer password than most people will create, but if you force it to be 18 characters and it's random you can get there. Besides, there's no reason to have humans generate the password, have a program do it. I have a password manager and I regularly create 20+ character passwords with it. $\endgroup$ Commented Aug 8 at 1:36
  • $\begingroup$ True, but that is more like entering a key rather than a password. I admit that nobody with a sound mind would remember a random-enough password anyway - that is something you might do with your system's password but not one protecting a key store. Still, if the count would have been 1,000,000 rather than 1,000 then it would at least have added some level of inherent security, so that a smaller password could be used - although typing 15 instead of 18 characters doesn't make a huge difference either. It would matter for smaller passwords though. $\endgroup$
    – Maarten Bodewes
    Commented Aug 8 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.