2011-02-13 7 views
8

Tengo una cadena binaria de 56 bits que quiero usar como la clave secreta para el cifrado DES.Crear clave DES desde cadena binaria de 56 bits

me encontré con el siguiente código en la página web docs JCA

byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, 
(byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 }; 
DESKeySpec desKeySpec = new DESKeySpec(desKeyData); 
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 
SecretKey secretKey = keyFactory.generateSecret(desKeySpec); 

Sin embargo, este utiliza 8 bytes para la clave (en lugar de 7). No está claro si el desKeyData [0] corresponde al byte menos significativo o el más significativo. Además, ¿es posible utilizar la cadena de 56 bits directamente para generar la matriz de bytes que se puede utilizar para este fin?

+1

Una entrada de 8 bytes normalmente significa que está utilizando los 7 bits menos significativos de cada byte. –

+0

y cual byte es el mas significativo? ¿el 0 o el 7? – AnkurVj

+1

Lo más importante, ¿por qué en el mundo seguimos usando DES en 2011? (El primero en responder "compatibilidad con versiones anteriores" ganará la insignia "¿No has conseguido mi punto?" – CAFxX

Respuesta

7

De Wikipedia:

La clave consiste ostensiblemente de 64 bits; sin embargo, solo 56 de estos son realmente utilizados por el algoritmo. Ocho bits se usan únicamente para verificar la paridad, y luego se descartan. Por lo tanto, la longitud efectiva de la clave es de 56 bits, y nunca se cita como tal. Cada octavo bit de la clave seleccionada se descarta, es decir, las posiciones 8, 16, 24, 32, 40, 48, 56, 64 se eliminan de la clave de 64 bits, dejando solo la clave de 56 bits.

Por lo tanto, los bits menos significativos (es decir, los bits 0 ª) no se utilizan para la construcción de llave, que pueden ser utilizados para la comprobación de paridad por DESKeySpec.isParityAdjusted().

EDIT: prueba simple que muestra que los bits menos significativos se ignoran:

SecretKeyFactory sf = SecretKeyFactory.getInstance("DES"); 
byte[] in = "test".getBytes("UTF-8"); 

Cipher c1 = Cipher.getInstance("DES"); 
c1.init(Cipher.ENCRYPT_MODE, sf.generateSecret(new DESKeySpec(
    new byte[] {0x10,0x20,0x30,0x40,0x50,0x60,0x70,(byte) 0x80}))); 
byte[] r1 = c1.doFinal(in); 

Cipher c2 = Cipher.getInstance("DES"); 
c2.init(Cipher.ENCRYPT_MODE, sf.generateSecret(new DESKeySpec(
    new byte[] {0x11,0x21,0x31,0x41,0x51,0x61,0x71,(byte) 0x81}))); 
byte[] r2 = c2.doFinal(in); 

assertArrayEquals(r1, r2); 
+0

posiciones de bit 8,16, etc. ¿esto no significa bits más significativos de cada byte en lugar de bits menos significativos? – AnkurVj

+0

Comenzando en uno, los bits de paridad son los más significativos de cada byte. – vz0

2

Un poco significativa es la que cambia el signo de un número one o two's complement. La idea de un bit más o menos significativo no se puede aplicar a bytes.

Como la respuesta axtavt dice, de todos los 64 bits de la secuencia, solo los bits en los rangos: (1..7), (9..15), (17..23), (25..31), (33..39), (41..47), (49..55), (57..63) se utilizan como la clave real. Por ejemplo, los 56 bits relevantes en la secuencia convertida a 1 son: 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, dejando los bits más significativos a cero como verificación de paridad.

Para convertir realmente una secuencia de 7 bytes y 56 bits a una secuencia de 8 bytes, puede usar this code.

+0

Del código al que se refiere, estableciendo un bit de paridad: 'result [7-resultIx/8] | = 1;'. Se usan bits menos significativos para la verificación de paridad en este caso. – axtavt

+0

@axtavt si divido mi cadena binaria de 56 bits en una gran matriz de bytes endian, el msb de cualquier byte puede ser '1', pero el tipo de datos de bytes no lo permite (su rango es -2^7-1 a 2^7-1). ¿El tipo de conversión es la solución correcta para esto? Quiero saber que si escribo estos en bytes, ¿seguiré utilizando la misma clave que quería usar? – AnkurVj

Cuestiones relacionadas