*** 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?
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