usuarios tipo tabla password para funcion encriptar desencriptar crear contraseñas contraseña campo .net sql mysql sql-server encryption

.net - tipo - funcion password mysql



Simular el cifrado de contraseñas() de MySql con.NET o MS SQL (7)

Estoy actualizando una vieja aplicación web ASP / MySql a ASP.NET/MS SQL.

Nos gustaría mantener los inicios de sesión del antiguo sitio web trabajando en la nueva aplicación.

Lamentablemente, las contraseñas se almacenaron en la base de datos MySql utilizando la función de contraseña () de MySql.

¿Es posible simular la función de contraseña () de MySql en .NET o MS SQL?

Cualquier ayuda / enlaces son apreciados.


No podrá simular la función de contraseña de MySql (). al menos no sin mucho trabajo y suerte. Siendo que MySql usa su propio algoritmo para encriptar cadenas de una sola dirección, no van a revelar qué algoritmo usan; lo que significa que tendría que hacer pruebas y errores, comparar las cadenas resultantes, etc.

Para solucionar su problema:

Replicaría el DB pero mantendría una conexión con MySql. Use una bandera para identificar un inicio de sesión por primera vez. Pídales que usen su contraseña actual; verifique la contraseña con la función de contraseña de MySql (). Si la contraseña es válida; pídales que lo reinicien, ya sea ingresando la misma contraseña nuevamente o una nueva; en este punto, use su algoritmo de encriptación favorito y almacene el resultado en su MS Sql DB.

Sé que suena como un dolor, pero es lo mejor que puedes hacer si no intentas hackear tu camino para descifrar el algoritmo de encriptación de MySql.

¡Buena suerte!


Puede encriptar cadenas usando MD5 o SHA1 en .Net, pero el algoritmo real utilizado por MySQL es probablemente diferente de estos dos métodos. Sospecho que está basado en algún tipo de ''sal'' basado en la instancia del servidor, pero no sé.

En teoría, dado que creo que MySQL es de código abierto, podrías investigar la fuente y determinar cómo se hace.

http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_password

Edición 1: creo que el algoritmo utilizado es un doble SHA1 con otros ''ajustes'' (según esta publicación del blog).


Para VB net, este rellena con 0 a la izquierda para que cuando el código hexadecimal sea [por ejemplo] ''E'', esta función anexará correctamente ''0E'' a la cadena de resultados. De modo que, al final, incluido el ''*'' preanimado, la cadena resultante tendrá 41 caracteres, como se requiere en MySQL

Public Function GenerateMySQLHash(ByVal strKey As String) As String Dim keyArray As Byte() = System.Text.UTF8Encoding.UTF8.GetBytes(strKey) Dim enc = New Security.Cryptography.SHA1Managed() Dim encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)) Dim myBuilder As New System.Text.StringBuilder(encodedKey.ToString.Length) For Each b As Byte In encodedKey myBuilder.Append(Strings.Right("0" & b.ToString("X"), 2)) Next Return "*" & myBuilder.ToString() End Function


"No van a revelar qué algoritmo usan"

erm ... alguien debería despertarse y decirle que MySQL es OPEN SOURCE ... no necesitan "divulgar" algo porque todos pueden leer la estructura misma de la base de datos - solo descargue las fuentes, busque las funciones de encriptación (i) Supongo que están usando C ++) y comienzan a investigar ... SHA1 parece bastante inseguro ahora - recientemente algunos científicos han demostrado que es posible elegir hasta el 20% de los datos sin limitaciones y producir el mismo hash, por lo que uno sería se aconseja utilizar AES o SHA2 (por lo tanto, no MySQL- PASSWORD -func)


las funciones de contraseña de mysql no son particularmente seguras (por ejemplo, no hay sal ni ningún otro método de protección contra la búsqueda de hashes) las únicas razones que puedo ver para querer duplicar el algoritmo son 1: tiene una lista / tabla de usuarios con contraseña mysql () s 2: quieres descifrar las contraseñas de mysql de los hashes en la tabla de usuarios.

De lo contrario, utilice algo diferente, por ejemplo, un hash que combine tanto el nombre del usuario (y / o algún otro invariante de fila) como su contraseña. De esta forma, si dos usuarios eligen la misma contraseña, no será obvio. y si la tabla se expone, la seguridad no disminuye a la misma velocidad (por ejemplo, google para 446a12100c856ce9 que es la contraseña () hash de una contraseña muy popular)


Según la documentación de MySQL, el algoritmo es un hash doble SHA1. Al examinar el código fuente de MySQL, encontrará una función llamada make_scrambled_password () en libmysql / password.c. La función se define de la siguiente manera:

/* MySQL 4.1.1 password hashing: SHA conversion (see RFC 2289, 3174) twice applied to the password string, and then produced octet sequence is converted to hex string. The result of this function is used as return value from PASSWORD() and is stored in the database. SYNOPSIS make_scrambled_password() buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string password IN NULL-terminated password string */ void make_scrambled_password(char *to, const char *password) { SHA1_CONTEXT sha1_context; uint8 hash_stage2[SHA1_HASH_SIZE]; mysql_sha1_reset(&sha1_context); /* stage 1: hash password */ mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) strlen(password)); mysql_sha1_result(&sha1_context, (uint8 *) to); /* stage 2: hash stage1 output */ mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE); /* separate buffer is used to pass ''to'' in octet2hex */ mysql_sha1_result(&sha1_context, hash_stage2); /* convert hash_stage2 to hex string */ *to++= PVERSION41_CHAR; octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE); }

Dado este método, puede crear una contraparte .NET que básicamente haga lo mismo. Esto es lo que se me ocurrió. Cuando ejecuto SELECT PASSWORD (''prueba''); contra mi copia local de MySQL, el valor devuelto es:

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

De acuerdo con el código fuente (nuevamente en password.c), el asterisco inicial indica que este es el método posterior a MySQL 4.1 para encriptar la contraseña. Cuando emulo la funcionalidad en VB.Net, por ejemplo, esto es lo que se me ocurre:

Public Function GenerateMySQLHash(ByVal strKey As String) As String Dim keyArray As Byte() = Encoding.UTF8.GetBytes(strKey) Dim enc = New SHA1Managed() Dim encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)) Dim myBuilder As New StringBuilder(encodedKey.Length) For Each b As Byte In encodedKey myBuilder.Append(b.ToString("X2")) Next Return "*" & myBuilder.ToString() End Function

Tenga en cuenta que SHA1Managed () está en el espacio de nombres System.Security.Cryptography. Este método devuelve el mismo resultado que la llamada PASSWORD () en MySQL. Espero que esto te ayude

Editar: Aquí está el mismo código en C #

public string GenerateMySQLHash(string key) { byte[] keyArray = Encoding.UTF8.GetBytes(key); SHA1Managed enc = new SHA1Managed(); byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)); StringBuilder myBuilder = new StringBuilder(encodedKey.Length); foreach (byte b in encodedKey) myBuilder.Append(b.ToString("X2")); return "*" + myBuilder.ToString(); }


Versión de C # modificada para corregir el problema de relleno.
[Prueba] public void GenerateMySQLHashX2 () {string password = "20iva05";

byte[] keyArray = Encoding.UTF8.GetBytes(password); SHA1Managed enc = new SHA1Managed(); byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)); StringBuilder myBuilder = new StringBuilder(encodedKey.Length); foreach (byte b in encodedKey) { log.Debug(b.ToString() + " -> " + b.ToString("X2")); myBuilder.Append(b.ToString("X2")); } Assert.AreEqual("*8C2029A96507478FD1720F6B713ADD57C66EED49", "*" + myBuilder.ToString()); }