tribbloid
tribbloid

Reputation: 3858

Why keys generated from a Java DES KeyGenerator have incorrect size?

I'm using Java's SunJCE provider to generate a 7 bit key:

    KeyGenerator v = KeyGenerator.getInstance("DES")
    Provider p = v.getProvider
    assert(p.getClass().getSimpleName() == "SunJCE")
    v.init(56)
    Key k = v.generateKey()
    assert(k.getEncoded().getLength == 7)

When I run the above program, I got the error that indicated that the length of k is actually 8 (64 bit) instead of 56 bit, the strange thing is that the KeyGenerator is initialized to generate only 56 bit key, so why the actual length of k is incorrect?

Upvotes: 1

Views: 333

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94038

DES keys are encoded using 8 bits for each 7 bits, where the least significant bit of each byte is used to make the number of bits odd. So if the first 7 bits have 6, 4 or 2 bits set to one then the least significant one is set (to one). It is reset / unset / left at zero otherwise. So a 56 bit DES key is encoded as 64 bits / 8 bytes, a 112 bit 2 key used for triple DES is encoded as 128 bits and 168 bits DES keys are encoded using 192 bits.

The parity bits can be used as some kind of check to see if the DES key hasn't been altered (although it isn't very good for that either). Most DES implementations will nowadays simply ignore the parity bits altogether, but the Java KeyGenerator will still correctly set them. You can test this by validating Integer.bitCount(b & 0xFF) % 2 == 1 for each byte b in the resulting key: it should always return true.


More modern symmetric ciphers try to use fully (pseudo-)random keys; 256 bit AES or HMAC keys consist simply of randomized bytes.

This isn't true for most asymmetric ciphers; encoding the public or private key of most asymmetric ciphers will result in significantly more bits than the key size. The key size for asymmetric ciphers is usually the size of the parameter that determines the strength of the key, e.g. the size of the modulus for RSA.


Notes:

  • DES only has a key size (and strength) of 56 bits, and is considered completely broken: use a key of 128 bits or more (which also rules out two-key 112 bit triple DES keys, if you were paying attention) and a modern cipher such as AES.
  • Your assertions test things that should always be true and make little sense to me. If anything should be tested it is the random number generator that is used to generate the keys (and those are notoriously hard to test, unfortunately).
  • When testing for the provider name - a dangerous and non-portable practice if you ask me - then you should at least use Provider#getName() (and possibly the other getters that return useful info about the provider) rather than the class name. The class name is an implementation detail and could actually change - even if the provider name doesn't.

Upvotes: 2

Related Questions