2011-12-28 23 views
6

Mi organización ha decidido encriptar ciertos datos en nuestra base de datos, y se me ha encomendado la tarea de implementar el cifrado. Necesito poder encriptar los datos, almacenar la versión encriptada en un campo VARCHAR en nuestra base de datos, y luego recuperarla y descifrarla de nuevo a su estado habitual.¿Cómo puedo implementar una encriptación fuerte y reversible que interopera entre ASP.NET 2.0, Coldfusion 5 y Classic ASP?

En la superficie parece una tarea simple. Hay una serie de formas de implementar el cifrado. Uno que he usado anteriormente se basa en el código de cifrado AES que se encuentra en this StackOverflow question.

Lo que lo hace más difícil en este caso, es necesario escribir código para cifrar/descifrar los datos en varias aplicaciones que acceden a nuestra base de datos, algunas de las cuales se desarrollan utilizando diferentes tecnologías. Tenemos aplicaciones escritas en Coldfusion 5, en Classic ASP y en ASP.NET 2.0. Necesito ser capaz de cifrar datos y almacenarlos en la base de datos con el código de Coldfusion, y luego leerlos y descifrarlos de nuevo a su forma original en ASP.NET. O encriptarlo en ASP clásico y descifrarlo en Coldfusion. O cualquier otra combinación de estas plataformas.

Esto ha resultado ser más difícil de lo que esperaba. Diferentes clases/objetos/funciones/bibliotecas que afirman usar los mismos algoritmos parecen generar resultados diferentes incluso cuando se les dan los mismos datos y el mismo secreto compartido. En el pasado, utilizamos CAPICOM para proporcionar interoperabilidad de cifrado entre Coldfusion y Classic ASP. Pero me he encontrado con problemas al intentar hacer que funcione en ASP.NET. He leído this article about how to get CAPICOM to work in .NET, pero las sugerencias no me han funcionado. Ni siquiera puedo generar una clase de interoperabilidad o importar una referencia al objeto COM sin obtener un error. Además, algunos de nuestros servidores de producción tienen sistemas operativos que no parecen ser compatibles con CAPICOM, por lo que puede ser un callejón sin salida de todos modos.

¿Alguien tiene alguna sugerencia sobre cómo puedo implementar el cifrado de tal manera que cualquiera de las 3 plataformas pueda descifrar lo que los otros han cifrado, mientras se sigue usando un algoritmo razonablemente fuerte?

Editar 2011-12-29:

Como se señaló en los comentarios a continuación, Actualmente estoy esperando encontrar una solución ASP.NET que es compatible con algunos de código ASP clásico nuestra Coldfusion existente/que utiliza CAPICOM. La razón de esto es que nuestro jefe de equipo no quiere que introduzca un nuevo método de encriptación en nuestro código para nuestro propósito actual, a menos que también revise nuestras aplicaciones más antiguas usando encriptación para un propósito diferente de usar el mismo método. Él quiere usar el mismo método de encriptación para ambos propósitos. Desde que revisar nuestras aplicaciones antiguas para usar un nuevo método de encriptación significa no solo cambiar el código, sino también rastrear todos los datos encriptados por las aplicaciones anteriores, descifrarlo y volver a encriptarlo usando el nuevo método, dudo en ir. esa ruta a menos que sea necesario. Con suerte, encontraré la manera de que ASP.NET lea los datos encriptados existentes.

Los datos cifrados de nuestras otras aplicaciones Coldfusion y ASP Classic se codificaron utilizando el objeto COM de CAPICOM. Por lo que puedo decir, la configuración ha sido universalmente el cifrado AES, el tamaño máximo de la clave (que creo que es de 256 bits en AES).

En @ petición de Leigh, aquí es un ejemplo simplificado de cómo nuestras aplicaciones CF existentes utilizan CAPICOM:

<cfscript> 
    encryptObject = CreateObject("com","CAPICOM.EncryptedData"); 
    encryptObject.Algorithm.Name = 4; // 4 is AES 
    encryptObject.Algorithm.KeyLength = 0; // 0 is MAX, I believe 256-bit in the case of AES 
    encryptObject.SetSecret(sharedSecret); 
    encryptObject.Content = stringToEncrypt; 

    encryptedData = localScope.encryptObject.Encrypt(); 
</cfscript> 
+0

Por favor, prestar más atención a sus opciones de etiquetas. La etiqueta 'asp' resultó ambigua, y fue limpiada a favor de 'asp-classic'. Habría tenido la única pregunta sobre Stack Overflow etiquetada 'asp', y eso debería haber enviado una gran bandera roja. –

+0

@Joel Mis disculpas. No me di cuenta, pero miraré más cuidadosamente en el futuro. –

+0

¿Qué producto de base de datos está utilizando? –

Respuesta

6

Puesto que usted tiene la plataforma de base de datos común entre todos los sistemas, que dejaría el cifrado/descifrado ahí.He aquí un artículo sobre el cifrado-columna específica dentro de SQL 2005:

http://msdn.microsoft.com/en-us/library/ms179331(v=sql.90).aspx

+0

Gracias! Esa es una sugerencia sólida. No tenía idea de que era una opción. Voy a ejecutar eso por el equipo y ver si alguien tiene un problema con él. –

+1

Simplemente no almacene la clave en la base de datos. –

+0

Esta es una buena sugerencia. Lo ejecuté por el líder del proyecto, y él dijo que estaba bien que lo usara ** SI ** Modifiqué todo nuestro código de cifrado/descifrado existente para que también estuviera basado en SQL, por lo que nuestros métodos son consistentes. Ugh. Eso todavía está sobre la mesa, pero será menos trabajo si puedo encontrar el código ASP.NET que funciona bien con el método CAPICOM que usamos en CF y ASP clásico en el pasado. Así que voy a seguir intentándolo por ahora. –

2

que acabo de hacer una cosa similar (el cifrado entre el clásico ASP y ASP .NET, haciendo caso omiso de ColdFusion) y me encontré con CAPICOM varias veces también, pero después de un montón de toing y froing (y búsqueda) encontré una biblioteca COM AES/Rijndael que terminé usando, Hyeongryeol.Security.Cryptography (por alguna razón la descarga se llama .wma - es un archivo zip, así que ábralo manualmente con 7-Zip o lo que sea que uses).

El cifrado/descifrado en .NET utiliza la clase RijndaelManaged (hay un ejemplo en la descarga).

All-in-all es muy simple de poner en práctica. Simplemente registre la DLL COM (para la ASP clásica) y debería estar listo. He aquí un extracto de nuestra build.bat que asegura (esperanza) que está registrado:

echo Registering HyeongryeolStringEncrypter.dll 
copy Libraries\Hyeongryeol.Security.Cryptography\ASP\HyeongryeolStringEncrypter.dll %system32%\HyeongryeolStringEncrypter.dll 
regsvr32 /s %system32%\HyeongryeolStringEncrypter.dll 

Sólo asegúrese de que utiliza la misma clave/IV cada lado.

+0

Conozco la clase 'RijndaelManaged', pero no estoy seguro de cómo hacerlo para jugar bien con las funciones de criptografía disponibles para ASP y CF. Por ejemplo, una cosa que no entiendo: en nuestro código ASP clásico existente cuando encriptamos con CAPICOM, solo necesitamos configurar los datos, el método de cifrado y la clave. Pero la función 'CreateEncryptor' de la clase RijndaelManaged quiere una clave y un _vector_. ¿Qué es un vector, por qué CAPICOM no lo requiere y qué puedo pasar a 'CreateEncryptor' que arroje los mismos resultados que CAPICOM? –

+0

Si utiliza la DLL COM de Hyeongryeol, no necesita usar CAPICOM. Hyeongryeol acepta un parámetro clave/IV (el mismo que RijndaelManaged) y en todas mis pruebas pude encriptar/desencriptar cadenas satisfactoriamente en el lado ASP o ASP .NET y obtener el mismo resultado. – akiller

+0

Entendido. Desafortunadamente, ya tenemos algunas aplicaciones que usan CAPICOM, y sería ideal si la solución para este proyecto fuera compatible. Voy a intentar encontrar primero un método de descifrado ASP.NET que sea compatible con nuestro código CAPICOM actual. Si no puedo encontrar uno, investigaré el cifrado basado en Hyeongryeol o SQL Server. –

0

El cifrado solo está modificando sus datos para que no sean legibles por el ser humano y luego lo modifique utilizando el reverso de la fórmula original.

Personalmente me quedaría con AES y debería poder obtener AES para esas plataformas.

Dependiendo de lo fuerte que quieras que sea, puedes simplemente escribir una función simple para hacerlo tú mismo.

Podría ser tan simple como agregar una serie de bits a la información basada en alguna clave.

1

Después de una extensa búsqueda en varios sitios, otros sugirieron SSO pero obviamente con limitaciones, llegué al código a continuación que me permitió lo que quería.

  1. Tenemos un sitio de CF existente y lo estamos rediseñando utilizando ASP.NET y el proveedor de membresía.
  2. Queríamos mantener las contraseñas de CF existentes, pero transferirlas a la tabla aspnet_membership y asignarlas.
  3. También queríamos poder cambiar la contraseña de cualquiera de los sistemas, ya que se ejecutarán al mismo tiempo durante un máximo de 3 meses.
  4. Esto significa que queríamos poder actualizar la tabla aspnet_membership desde CF y autenticar también en esa tabla.

El siguiente código nos permite copiar la contraseña de CF y hacerla coincidir con la tabla aspnet_membership. Si theBased64Hash es igual que la contraseña en la tabla, entonces el usuario puede ser autenticado. Ahora podemos encriptar la contraseña si el usuario desea cambiar la contraseña desde el lado de CF, y todavía ser validado en ASP.NET.

actualización (solucionado el problema con la concatenación)

<cfscript> 
    thePassword = "originalPassword"; 
    base64Salt = "JZjdzUXREM0A7DPI3FV3iQ=="; 

    // extract bytes of the salt and password 
    saltBytes = binaryDecode(base64Salt, "base64"); 
    passBytes = charsetDecode(thePassword, "UTF-16LE"); 

    // next combine the bytes. note, the returned arrays are immutable, 
    // so we cannot use the standard CF tricks to merge them  
    ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils"); 
    dataBytes = ArrayUtils.addAll(saltBytes, passBytes); 

    // hash binary using java 
    MessageDigest = createObject("java", "java.security.MessageDigest").getInstance("SHA-1"); 
    MessageDigest.update(dataBytes);  
    theBase64Hash = binaryEncode(MessageDigest.digest(), "base64"); 

    WriteOutput("<br />theBase64Hash= "& theBase64Hash &"<br/>"); 
</cfscript> 
+0

Si es posible, debe cambiar a un algoritmo más seguro. [CFMX_COMPAT] (http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c2f.html) es extremadamente débil y solo se incluye por compatibilidad con versiones anteriores. – Leigh

+0

Gracias @Leigh por el código de muestra. Realmente está funcionando para nosotros. La razón por la que tuvimos que usar el hash SHA1 se debió al control de membresía de ASP.NET. – SollyM

+0

Sí, el código funciona. Simplemente no es muy seguro. De ahí la sugerencia de cambiar a un algoritmo más fuerte ;-) – Leigh

Cuestiones relacionadas