Hashing de contraseñas en ASP clásico
Código ASP clásico
- Por Programador ASP clásico /
- 29/03/2025 @ 16:49:42 /
- 1022 visitas
- En el mundo del desarrollo web, la seguridad de los usuarios debería ser siempre una prioridad. Y cuando hablamos de seguridad, uno de los aspectos más críticos es el almacenamiento seguro de contraseñas. Imagina esto: si tu aplicación sufre una brecha de seguridad y las contraseñas de tus usuarios están almacenadas en texto plano… ¡catástrofe total! Por eso, hoy vamos a hablar de hashing de contraseñas en ASP Clásico, una técnica fundamental para proteger la información sensible.
¿Qué es el Hashing y Por Qué es Importante?
El hashing es un proceso criptográfico que convierte una contraseña (o cualquier dato) en una cadena de caracteres única y prácticamente irreversible. A diferencia de la encriptación, que es bidireccional (se puede descifrar), un buen hash no se puede revertir.
Características de un Buen Hash
* Irreversibilidad: No debe haber forma de obtener la contraseña original a partir del hash.
* Determinista: La misma contraseña siempre genera el mismo hash.
*Resistente a colisiones: Dos contraseñas diferentes no deberían producir el mismo hash.
* Lento (sí, ¡lento!): Los algoritmos modernos están diseñados para ser computacionalmente costosos, lo que dificulta los ataques por fuerza bruta.
En ASP Clásico, aunque no tenemos las librerías más modernas de .NET, podemos implementar soluciones robustas con un poco de ingenio.
Algoritmos de Hashing Recomendados (y los que Debes Evitar)
MD5 y SHA-1: ¡No los uses!
Aunque alguna vez fueron populares, hoy son considerados inseguros. Se pueden romper con relativa facilidad usando técnicas como rainbow tables o ataques de colisión.
SHA-256, SHA-512: Mejores, pero no perfectos
Son más seguros que MD5, pero siguen siendo rápidos, lo que los hace vulnerables a fuerza bruta si no se usan con salting.
PBKDF2, bcrypt: Los Ganadores
Estos algoritmos están diseñados específicamente para contraseñas:
* PBKDF2 (Password-Based Key Derivation Function 2) aplica múltiples iteraciones de un hash (como SHA-256) junto con una sal (salt) para hacer el proceso más lento y seguro.
* bcrypt es aún mejor, ya que ajusta automáticamente la complejidad según la capacidad del hardware.
Lamentablemente, ASP Clásico no tiene soporte nativo para bcrypt, pero podemos implementar PBKDF2 con un poco de código VBScript y ayuda de librerías externas.
Cómo Implementar Hashing Seguro en ASP Clásico
1. Generar una Sal (Salt) Aleatoria
La sal es un valor aleatorio que se añade a la contraseña antes de hacer el hash. Esto evita que dos usuarios con la misma contraseña tengan el mismo hash y protege contra ataques de diccionario.
Function GenerateSalt(length)
Dim chars, salt, i, randomIndex
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"
salt = ""
Randomize
For i = 1 To length
randomIndex = Int((Len(chars) * Rnd()) + 1)
salt = salt & Mid(chars, randomIndex, 1)
Next
GenerateSalt = salt
End Function
2. Aplicar PBKDF2 o SHA-256 con Iteraciones
Para hacer el proceso más seguro, podemos aplicar múltiples iteraciones del hash.
Function HashPassword(password, salt, iterations)
Dim hashedPassword, i
hashedPassword = password & salt
For i = 1 To iterations
hashedPassword = SHA256(hashedPassword) ' Suponiendo que SHA256 es una función disponible
Next
HashPassword = hashedPassword
End Function
3. Almacenar el Hash y la Sal en la Base de Datos
Cuando un usuario se registra:
1. Generas una sal única.
2. Aplicas el hash a la contraseña + sal.
3. Guardas el hash resultante y la sal en la base de datos (nunca la contraseña original).
Cuando el usuario inicia sesión:
Recuperas su sal de la BD.
Aplicas el mismo hash a la contraseña ingresada + sal almacenada.
Comparas el resultado con el hash guardado.
4. El código para hashing de contraseñas en ASP clásico
Manos a la obra, vemos la forma de hacer el hashing de una contraseña:
<%
' ==============================================
' FUNCIONES PRINCIPALES
' ==============================================
Function GeneratePasswordHash(password)
On Error Resume Next
Dim salt, hashValue
salt = GenerateRandomString(32)
hashValue = CalculateHash(password, salt)
GeneratePasswordHash = hashValue & ":" & salt
If Err.Number <> 0 Then
Response.Write "Error GeneratePasswordHash: " & Err.Description
GeneratePasswordHash = ""
End If
On Error GoTo 0
End Function
Function VerifyPassword(password, storedHashWithSalt)
On Error Resume Next
Dim storedParts, storedHash, storedSalt
storedParts = Split(storedHashWithSalt, ":")
If UBound(storedParts) <> 1 Then
VerifyPassword = False
Exit Function
End If
storedHash = storedParts(0)
storedSalt = storedParts(1)
VerifyPassword = (CalculateHash(password, storedSalt) = storedHash)
If Err.Number <> 0 Then
Response.Write "Error VerifyPassword: " & Err.Description
VerifyPassword = False
End If
On Error GoTo 0
End Function
' ==============================================
' FUNCIONES AUXILIARES
' ==============================================
Function CalculateHash(password, salt)
On Error Resume Next
Dim algorithm, hash, saltedPassword, bytes, hashBytes
algorithm = "SHA512"
saltedPassword = salt & password
Set hash = Server.CreateObject("System.Security.Cryptography.SHA512Managed")
bytes = UTF8Encode(saltedPassword)
hashBytes = hash.ComputeHash_2((bytes))
CalculateHash = BytesToHex(hashBytes)
If Err.Number <> 0 Then
Response.Write "Error CalculateHash: " & Err.Description
CalculateHash = ""
End If
On Error GoTo 0
End Function
Function GenerateRandomString(length)
On Error Resume Next
Dim chars, result, i, randomIndex
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
Randomize
result = ""
For i = 1 To length
randomIndex = Int((Len(chars) * Rnd()) + 1)
result = result & Mid(chars, randomIndex, 1)
Next
GenerateRandomString = result
If Err.Number <> 0 Then
Response.Write "Error GenerateRandomString: " & Err.Description
GenerateRandomString = ""
End If
On Error GoTo 0
End Function
Function UTF8Encode(str)
On Error Resume Next
Dim stream
Set stream = Server.CreateObject("ADODB.Stream")
stream.Open
stream.Type = 2 ' Text
stream.Charset = "utf-8"
stream.WriteText str
stream.Position = 0
stream.Type = 1 ' Binary
stream.Position = 0
UTF8Encode = stream.Read
stream.Close
Set stream = Nothing
If Err.Number <> 0 Then
Response.Write "Error UTF8Encode: " & Err.Description
UTF8Encode = ""
End If
On Error GoTo 0
End Function
Function BytesToHex(bytes)
On Error Resume Next
Dim hexStr, i, byteVal
hexStr = ""
For i = 1 To LenB(bytes)
byteVal = AscB(MidB(bytes, i, 1))
hexStr = hexStr & Right("0" & Hex(byteVal), 2)
Next
BytesToHex = LCase(hexStr)
If Err.Number <> 0 Then
Response.Write "Error BytesToHex: " & Err.Description
BytesToHex = ""
End If
On Error GoTo 0
End Function
%>
<%
' --------------------------------------------------
' CÓDIGO PARA PROBAR HASHING
' --------------------------------------------------
' 1. Primero genera un hash de una contraseña
Dim miPassword, hashGenerado
miPassword = "hola" ' Cambia esto para probar
hashGenerado = GeneratePasswordHash(miPassword)
Response.Write "Contraseña original: " & miPassword & "
"
Response.Write "Hash generado: " & hashGenerado & "
"
' 2. Luego verifica si otra contraseña coincide
Dim pruebaPassword, esValida
pruebaPassword = "hola" ' Cambia esto para probar (usa una diferente para ver el fallo)
esValida = VerifyPassword(pruebaPassword, hashGenerado)
If esValida Then
Response.Write pruebaPassword & "' ES VÁLIDA (coincide con el hash)"
Else
Response.Write pruebaPassword & "' NO VÁLIDA (no coincide con el hash)"
End If
%>
No Subestimes la Seguridad
Aunque ASP Clásico es una tecnología antigua, eso no significa que debamos descuidar la seguridad. Implementar hashing con sal y algoritmos robustos como PBKDF2 puede marcar la diferencia entre una aplicación vulnerable y una que protege adecuadamente a sus usuarios.
Si puedes, usa SSL/TLS para todas las comunicaciones y nunca envíes contraseñas en texto plano por HTTP. ¡Seguridad en capas es la clave!
tags: hashing, contraseñas, ASP Clásico, seguridad, criptografía, PBKDF2, bcrypt, SHA-256, sal, almacenamiento seguro, ataques, fuerza bruta, rainbow tables, VBScript
En esta sección encontrarás una mezcla de códigos recopilados de fuentes públicas de Internet y otros creados por ASP TEAM. Compartimos recursos útiles de buena fe para formar una base de conocimiento en el desarrollo de aplicaciones en ASP Clásico.