Ningún esquema como este evitará que un atacante determinado active la "función de depuración", por el simple expediente de ingeniería inversa del código para ubicar la parte que, en el código del software, se verá así:
if (is_good_password(password)) {
activate_debug();
}
y convertirlo en:
if (true) {
activate_debug();
}
que generalmente es solo una cuestión de convertir un salto condicional en un salto incondicional, o un salto no condicional (es decir, un código de operación nop
). Ni siquiera es difícil de hacer, incluso en grandes piezas de software (por ejemplo, lo hice una vez para Windows 2000, para permitir una prueba personalizada CSP : CSP debe estar firmado, y la solución provista por Microsoft para desactivar la verificación de firmas en plataformas de desarrollo era válida solo para Win2k SP2 o WinXP, mientras tenía un Win2k SP4, así que tuve que hackear el advapi32.dll
, que me tomó 3 horas).
Dicho esto, si solo desea verificar una contraseña, la forma más fácil es almacenar en su software un token de verificación de contraseña, es decir, un valor de hash calculado sobre la contraseña. ¡No es necesario traer toda la parafernalia de las firmas digitales! Solo un simple hash, y esto puede acomodar contraseñas de cualquier longitud. El software incorpora el valor de hash; cuando se ingresa la URL de "depuración", la clave aparece después del " debug/
" y ve si coincide con el valor de hash registrado. Por lo tanto, la contraseña no aparece en el código del software (ni en texto claro, o simplemente "codificado"), y puede usar una "contraseña" lo suficientemente corta como para escribirla.
Las firmas digitales son buenas aquí solo si tiene un número ilimitado de "Debbies", y desea poder dar una "contraseña de depuración" a cada Debbie, de modo que cada Debbie tenga su propia contraseña distinta de las contraseñas dadas a los demás Debbies, y desea hacer que sea imposible para una Debbie malvada, independientemente de la ingeniería inversa que haga, para volver a calcular las otras contraseñas de la que ella ya tiene (si solo tiene, por ejemplo, 20 Debbies, solo puede incluir 20 valores hash en su código; por "ilimitado" quiero decir "potencialmente millones"). Este es un escenario bastante específico. Un ejemplo son las "claves de producto": las firmas digitales teóricamente podrían frustrar los generadores de clave de producto. Sin embargo, la firma digital más fuerte no funcionará mejor que un hash de contraseña contra un atacante que realiza algunas horas de ingeniería inversa en el código para localizar el código de operación de salto condicional correcto. La firma no protegería contra el acceso ilícito al código de depuración; protege solo contra la extensión de un acceso ilícito a una escala industrial, dándole a muchos otros clientes sin requerir una modificación local del código, lo que se denomina "pirateo" .
Para la función hash, si tiene dudas, use SHA-256 - si (y solo si) la "contraseña" es lo suficientemente larga y aleatoria (por ejemplo, 128 bits aleatorios). Si se le permite a Debbie elegir una contraseña "significativa" (una que un ser humano podrá recordar, en lugar de tenerla escrita en un pedazo de papel), entonces debe usar una función hash que resista los ataques de diccionario, p.ej PBKDF2 or bcrypt .
No utilice la forma de "cifrar con la clave privada" para describir una firma; Es una explicación terrible, que no funciona para todos los algoritmos de firma. Es solo una forma histórica con la que RSA se presentó por primera vez, pero incluso para RSA es incorrecta: no tiene en cuenta el relleno , y el relleno es esencial para la seguridad (consulte PKCS # 1 ). Solo olvídalo. No hay nada de malo en "usar la clave privada para firmar algunos datos" y "usar la clave pública para verificar algunos datos".