Does DESKey store invalid parity bits?

According to the DES specification, the last bit of each byte of the secret key is used to detect errors (each byte must have odd parity). Therefore, the effective key length is 56 bits, not 64 bits.

However, in many use cases, these parity bits are not checked. Sometimes they are even used for a completely different purpose: Mifare DESFire cards store the key version in these bits, for example, even if the original goal of error correction is lost.

How does the implementation of Java cards handle these bits? Let's look at this code:

DESKey desKey = ... //a single DES key instance
byte[] inputKey = new byte[8];
inputKey[7] = (byte) 0x03; //explicitly invalid parity bit in the last byte
desKey.setKey(inputKey, (short) 0);
byte[] outputKey = new byte[8];
desKey.getKey(outputKey, (short) 0);

It is guaranteed that the massifs inputKeyand outputKeywill contain the same data at the end, even with an invalid parity bits in inputKey? I have done several experiments with several types of cards, and all of them store any data that I put in these parity bits, but I did not find mention in the Java Card specification that this behavior is guaranteed.

This information is very important to me; otherwise, I would have to store my "invalid parity bits" separated from the key instance.

+4
source share
1 answer

, . ; , ( , , ).

. , . , , , - , MAC ( ).

, , . , Java SecretKeyFactory. , , , . , // .

, Java- (, , ), , (EEPROM/flash) . , Java Card ( ). : . DES.


, , , Java Card, ( for, inlining , ). () .

/**
 * This method takes byte value <code>b</code> and then sets or unsets the least significant bit
 * of that value in such a way that the parity of <code>b</code> is odd.
 * So this method returns either <code>b</code> or <code>b ^ 1</code>.
 * 
 * @param b the byte value
 * @return <code>b</code> with DES parity
 */
public static byte makeDESParity(final byte b) {
    byte x = b;
    // trick to calculate odd parity in the lsb of x
    x ^= x >>> 4;
    x ^= x >>> 2;
    x ^= x >>> 1;
    // but we want even parity in the lsb: ~x
    // get the least significant bit: ~x & 1
    // xor that with b: ~x & 1 ^ b
    return (byte) (~x & 1 ^ b);
}

/**
 * This method takes byte value <code>b</code> and returns true if and only if
 * the byte has odd parity.
 * 
 * @param b the byte value
 * @return true if <code>b</code> has DES parity
 */
public static boolean hasDESParity(byte b) {
    // trick to calculate odd parity in the lsb of b
    b ^= b >>> 4;
    b ^= b >>> 2;
    b ^= b >>> 1;
    // check if last bit has indeed been set
    return (b & 1) != 0;
}
+3

Source: https://habr.com/ru/post/1683724/


All Articles