2010-04-14 10 views
5

*** sweet - gracias a Edward Smith por la CF Technote que indicó que la clave de ColdFusion estaba codificada en Base64. Ver generateKey() para el 'arreglo'¿Cómo hacer coincidir el cifrado de ColdFusion con Java 1.4.2?

Mi tarea consiste en utilizar Java 1.4.2 para que coincida con los resultados de un ejemplo de código de ColdFusion para el cifrado.

conocidos/valores dados:

  • Una clave de 24 bytes
  • Una sal de 16 bytes (IVorSalt)
  • codificación es Hex
  • algoritmo
  • cifrado es AES/CBC/PKCS5Padding
  • Un valor de texto claro de muestra
  • El valor cifrado del texto claro de muestra después de pasar por el código de ColdFusion

Supuestos:

  • número de iteraciones no especificados en el código ColdFusion por lo que suponen sólo una iteración
  • clave de 24 bytes, así que supongo de 192 bits de cifrado

Dada/ColdFusion de trabajo ejemplo de código de cifrado:

<cfset ThisSalt = "16byte-salt-here"> 
<cfset ThisAlgorithm = "AES/CBC/PKCS5Padding"> 
<cfset ThisKey = "a-24byte-key-string-here"> 
<cfset thisAdjustedNow = now()> 
<cfset ThisDateTimeVar = DateFormat(thisAdjustedNow , "yyyymmdd")> 
<cfset ThisDateTimeVar = ThisDateTimeVar & TimeFormat(thisAdjustedNow , "HHmmss")> 
<cfset ThisTAID = ThisDateTimeVar & "|" & someOtherData> 
<cfset ThisTAIDEnc = Encrypt(ThisTAID , ThisKey , ThisAlgorithm , "Hex" , ThisSalt)> 

Mi Java 1.4.2 cifrado código/descifrado botín:

package so.example; 

import java.security.*; 
import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.binary.*; 

public class SO_AES192 { 

private static final String _AES = "AES"; 
private static final String _AES_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding"; 
private static final String KEY_VALUE = "a-24byte-key-string-here"; 
private static final String SALT_VALUE = "16byte-salt-here"; 
private static final int ITERATIONS = 1; 

private static IvParameterSpec ivParameterSpec; 

public static String encryptHex(String value) throws Exception { 
    Key key = generateKey(); 

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding); 
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes()); 
    c.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec); 

    String valueToEncrypt = null; 
    String eValue = value; 
    for (int i = 0; i < ITERATIONS; i++) { 
//   valueToEncrypt = SALT_VALUE + eValue; // pre-pend salt - Length > sample length 
     valueToEncrypt = eValue;  // don't pre-pend salt Length = sample length 
     byte[] encValue = c.doFinal(valueToEncrypt.getBytes()); 
     eValue = Hex.encodeHexString(encValue); 
    } 
    return eValue; 
} 

public static String decryptHex(String value) throws Exception { 
    Key key = generateKey(); 

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding); 
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes()); 
    c.init(Cipher.DECRYPT_MODE, key, ivParameterSpec); 

    String dValue = null; 
    char[] valueToDecrypt = value.toCharArray(); 
    for (int i = 0; i < ITERATIONS; i++) { 
     byte[] decordedValue = Hex.decodeHex(valueToDecrypt); 
     byte[] decValue = c.doFinal(decordedValue); 
//   dValue = new String(decValue).substring(SALT_VALUE.length()); // when salt is pre-pended 
     dValue = new String(decValue); // when salt is not pre-pended 
     valueToDecrypt = dValue.toCharArray(); 
    } 
    return dValue; 
} 

private static Key generateKey() throws Exception { 
    // Key key = new SecretKeySpec(KEY_VALUE.getBytes(), _AES); // this was wrong 
    Key key = new SecretKeySpec(new BASE64Decoder().decodeBuffer(keyValueString), _AES); // had to un-Base64 the 'known' 24-byte key. 
    return key; 
} 

} 

I no puede crear un valor coincidente cifrado ni descifrar un valor cifrado dado. Supongo que tiene que ver con la forma en que manejo el vector/sal inicial.

No soy muy astuto, pero creo que debería poder tomar el texto claro de muestra y producir el mismo valor encriptado en Java que ColdFusion. Puedo cifrar/descifrar mis propios datos con mi código Java (por lo que soy coherente) pero no puedo comparar ni descifrar el valor cifrado de la muestra de ColdFusion.

Tengo acceso a un servicio web local que puede probar el resultado cifrado. La muestra de salida ColdFusion dada pasa/descifra bien (por supuesto). Si trato de descifrar la misma muestra con mi código Java (usando la clave real y la sal) obtengo el error "Dado que el bloque final no está bien ajustado". Obtengo el mismo resultado neto cuando paso mi intento de encriptación (usando la clave real y la sal) al servicio web de prueba.

¿Alguna idea?

Respuesta

4

Es el valor en el Coldfusion ThisKey:

<cfset ThisKey = "a-24byte-key-string-here"> 

exactamente la misma cadena que se devuelve desde la función() GenerateKey java? Creo que deben ser la misma cadena para que el texto encriptado generado sea el mismo.

utilizar una clave fija de esa manera en la FQ, es posible que tenga que seguir este del CF technote de cifrado fuerte:

es posible que desee generar su propia clave por dos razones:

  1. Quiere hacer coincidir los detalles de otro software de cifrado.
  2. Quiere aumentar la resistencia al agrietamiento de sus datos cifrados mediante técnicas de criptoanálisis orientadas a patrones.

Por ejemplo, para crear un 32 bytes clave a utilizar con el algoritmo AES con el valor hexagonal:

8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c

que usaría las funciones de ColdFusion BinaryDecode y ToBase64 para crear la tecla:

<cfset myKey = 
ToBase64(BinaryDecode("8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c","Hex")> 
<cfset encrypted =Encrypt(myString, myKey, "AES")> 

EDIT: acabo de dar cuenta de que la clave (como se mencionó en su comentario) es base 64, por lo que si el método "GenerateKey" en Java se parece a:

private static Key generateKey() throws Exception { 
final byte[] decodedKey = new BASE64Decoder().decodeBuffer(KEY_VALUE); 
final Key key = new SecretKeySpec(decodedKey, _AES); 
return key; 
} 

Debe ser de oro.

+0

Gracias hombre - El método generateKey() crea un objeto clave que contiene el algoritmo "AES" y una matriz de bytes de la clave conocida para que coincida. PERO ... al parecer, la clave de muestra (aprobada en un documento de Word estaba codificada en bas64 y tenía que ser descodificada antes de poder usarla. Realicé el cambio y actualicé el código Java de muestra. Todo está bien en el mundo ... por ahora... – JohnTheBarber

Cuestiones relacionadas