What is the algorithm for the JCEKS PBE used to en

2019-09-11 01:08发布

I want to decrypt the private key in a Java JCEKS Keystore, and I do not want to use Java.

I can find a description of the PBEWithMD5AndTripleDES, but not the actual implementation.

This comment purportedly explains the derivation:

/**
 * This class implements a proprietary password-based encryption algorithm.
 * It is based on password-based encryption as defined by the PKCS #5
 * standard, except that is uses triple DES instead of DES.
 *
 * Here's how this algorithm works:
 *
 * 1. Create random salt and split it in two halves. If the two halves are
 *    identical, invert one of them.
 * 2. Concatenate password with each of the halves.
 * 3. Digest each concatenation with c iterations, where c is the
 *    iterationCount. Concatenate the output from each digest round with the
 *    password, and use the result as the input to the next digest operation.
 *    The digest algorithm is MD5.
 * 4. After c iterations, use the 2 resulting digests as follows:
 *    The 16 bytes of the first digest and the 1st 8 bytes of the 2nd digest
 *    form the triple DES key, and the last 8 bytes of the 2nd digest form the
 *    IV.
 *
 * @author Jan Luehe
 * @see javax.crypto.Cipher
 */

But, is that first concatenation, password + half-of-salt, or is it half-of-salt + password? Is the input of the following rounds password + digest, or is it digest + password.

Between 8-bit chars, or full 16-bit chars, and the possible combinations of concatenation, you would think that by trial and error I should have worked it out by now.

I know the salt, and the iterations, and the password, and even the plaintext that the ciphertext should decrypt to (i.e. I have the decrypted data).

Deriving a 24-byte DES3 key, whether fixing parity or leaving it alone, and an 8-byte IV, decrypting in DES3 CBC mode, I cannot recreate my plaintext.

What is the algorithm that this comment describes?

1条回答
你好瞎i
2楼-- · 2019-09-11 01:33

Thank you to erikson 1 who replied to a comment on this answer to another question, and to Ebbe M. Pedersen. In the end, I should have tripped over the answer in trying the different combinations but somehow missed it.

For those interested, once you open up the JKS and find the entry, the encrypted PKCS#8 shows the JCEKS algorithm 1.3.6.1.4.1.42.2.19.1 along with salt and iteration count parameters and with those and your 8-bit/char password you can decrypt the ciphertext to find the inner, unencrypted PKCS#8 holding your private key.

def jce_pbkdf1(password, salt, iterations)
  salts = [copy = salt.dup, copy.slice!((copy.length / 2)..-1)]
  octets = salts.map { |half| (iterations).times.inject(half) { |digest| OpenSSL::Digest.digest('md5', digest + password) } }.join
  return octets[0..23], octets[24..-1] // key (parity not set) and IV
end
查看更多
登录 后发表回答