encryption coldfusion cryptography sagepay

encryption - Cifre los formularios de SagePay utilizando ColdFusion



cryptography (1)

Estoy intentando seguir una especificación para un campo encriptado en SagePay 3.00 usando ColdFusion 10.

El requisito es cifrar la cadena como AES (tamaño de bloque de 128 bits) en modo CBC con relleno PKCS # 5 utilizando la contraseña proporcionada como la clave y el vector de inicialización y codificar el resultado en hexadecimal.

Es el "uso de la contraseña provista" que está causando el problema.

Por el momento tengo

myStr = ''assortednamevaluepairsetc''; providedPassword = ''abcdefghijklmnop''; myCrypt = Encrypt(myStr,providedPassword,''AES/CBC/PKCS5Padding'',''HEX'',providedPassword,1);

pero eso no funcionará porque el valor que me ha dado SagePay causa un error - "la clave especificada no es una clave válida para este cifrado: longitud de clave AES inválida" ya que tiene solo 16 caracteres de longitud

De acuerdo con los documentos de CF, necesita usar generateSecretKey para garantizar la longitud de clave para AES, así que lo he intentado pero, aunque da un resultado, no es el resultado correcto en términos de cifrado

myStr = ''assortednamevaluepairsetc''; providedPassword = ''abcdefghijklmnop''; mySecret = GenerateSecretKey(''AES''); myCrypt = Encrypt(myStr,mySecret,''AES/CBC/PKCS5Padding'',''HEX'',providedPassword,1);

Cualquier ayuda en esto recibió con gratitud.


utilice generateSecretKey para garantizar la longitud de clave para AES

Esa función solo se usa cuando necesita generar una clave de cifrado completamente nueva . Usted ya tiene uno. El objetivo principal de generateSecretKey es garantizar que genere una clave de cifrado segura, que sea lo suficientemente aleatoria .

no funcionará porque el valor que me ha dado SagePay provoca un error - "la clave especificada no es una clave válida para este cifrado: longitud de clave AES inválida" ya que tiene solo 16 caracteres de longitud

Una longitud de clave de 16 bytes (es decir, 128 bits) es aceptable para AES. El problema es que encrypt () espera que la "clave" sea una cadena codificada en base64 , que es aproximadamente treinta y tres por ciento más larga que una cadena simple. Cuando invoca cifrar (...), CF decodifica la cadena "clave" proporcionada en bytes, es decir, esencialmente haciendo esto:

<cfset keyBytes = binaryDecode(yourPassword, "base64")> <cfoutput>length = #arrayLen(keyBytes)# bytes</cfoutput>

Como su cadena de contraseña no está codificada en base64, la longitud de clave resultante es demasiado pequeña, es decir, (12) en lugar de (16) bytes. De ahí el mensaje de error.

La solución es codificar base64 primero. Cómo lo haces depende de la codificación de la cadena. Parece que es solo una cadena de texto sin formato (con suerte, una suficientemente aleatoria ... ). Si es así, use charsetDecode para decodificar la cadena del juego de caracteres correspondiente (es decir, utf-8, etcétera), luego binaryEncode it base64:

<cfset keyIVBytes = charsetDecode(yourKeyString, "utf-8")> <cfset base64Key = binaryEncode(keyIVBytes, "base64")>

Además, el parámetro iv debe ser binario. Como key y iv son uno en el mismo, simplemente use la matriz de bytes del paso anterior. Además, suelte el parámetro de iterations , ya que no se aplica. Con esos cambios, debería funcionar como se esperaba:

encrypt(myStr, base64Key,"AES/CBC/PKCS5Padding", "hex", keyIVBytes)

NB: No soy un experto en encriptación, pero ... usar la clave como iv no es una gran idea ... Puede que quiera consultar con ellos para ver si hay otras opciones.