Hi,

On Fri, 2006-03-24 at 11:57 +0100, Mark Wielaard wrote:
> OK, that is good. Do we actually have any alternative KeyStore format?
> If yes then we should as Roman says use this as default for now. 

I see we do, GKR, defined in gnu.javax.crypto.jce.keyring.GnuKeyring.
But KeyStore.getDefaultType() does still return jks. This is actually
bug http://gcc.gnu.org/PR25673

> I will send an email to FSF legal about using a (reimplementation) of
> the JKS format.

Done and answered. We are free to reimplement this. File formats and
algorithms aren't copyrightable, so any code we write to conform to the
description given (see below) is OK. Now all we need is someone willing
to actually implement this and add it as a standard KeyStore format we
support.

Cheers,

Mark

The format of JKS files is, from the start of the file: 

     1. Magic bytes. This is a four-byte integer, in big-endian byte
        order, equal to 0xFEEDFEED.
     2. The version number (probably), as a four-byte integer (all
        multibyte integral types are in big-endian byte order). The
        current version number (in modern distributions of the JDK) is
        2.
     3. The number of entrires in this keystore, as a four-byte integer.
        Call this value n
     4. Then, n times: 
             1. The entry type, a four-byte int. The value 1 denotes a
                private key entry, and 2 denotes a trusted certificate.
             2. The entry's alias, formatted as strings such as those
                written by DataOutput.writeUTF(String).
             3. An eight-byte integer, representing the entry's creation
                date, in milliseconds since the epoch. 
                
                Then, if the entry is a private key entry: 
                
                     1. The size of the encoded key as a four-byte int,
                        then that number of bytes. The encoded key is
                        the DER encoded bytes of the
                        EncryptedPrivateKeyInfo structure (the
                        encryption algorithm is discussed later).
                     2. A four-byte integer, followed by that many
                        encoded certificates, encoded as described in
                        the trusted certificates section.
                
                Otherwise, the entry is a trusted certificate, which is
                encoded as the name of the encoding algorithm (e.g.
                X.509), encoded the same way as alias names. Then, a
                four-byte integer representing the size of the encoded
                certificate, then that many bytes representing the
                encoded certificate (e.g. the DER bytes in the case of
                X.509). 
                
     5. Then, the signature.

Decrypting the key works as follows: 

     1. The key length is the length of the ciphertext minus 40. The
        encrypted key, ekey, is the middle bytes of the ciphertext.
     2. Take the first 20 bytes of the encrypted key as a seed value,
        K[0].
     3. Compute K[1] ... K[n], where |K[i]| = 20, n = ceil(|ekey| / 20),
        and K[i] = SHA-1(UTF-16BE(password) + K[i-1]).
     4. key = ekey ^ (K[1] + ... + K[n]).
     5. The last 20 bytes are the checksum, computed as H =
        SHA-1(UTF-16BE(password) + key). If this value does not match
        the last 20 bytes of the ciphertext, output FAIL. Otherwise,
        output key.

The signature is defined as SHA-1(UTF-16BE(password) + US_ASCII("Mighty
Aphrodite") + encoded_keystore). 

(Above, SHA-1 denotes the secure hash algorithm, UTF-16BE the big-endian
byte representation of a UTF-16 string, and US_ASCII the ASCII byte
representation of the string.) 

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to