jBcrypt es una implementación de Java. Las aplicaciones de Android están escritas en casi Java, para una máquina virtual casi Java llamada Dalvik .
Para tareas intensivas en computación, especialmente algoritmos criptográficos, Java incurre en una desaceleración típica de 3x en comparación con el código C equivalente optimizado: una buena máquina virtual Java ejecuta un compilador JIT , y el rendimiento del código estará limitado por las restricciones en las que debe funcionar una JVM (la traducción del código de bytes al código nativo debe ser rápida e incremental, los métodos se traducen por llamada) ; y el resultado todavía debe ser apropiado para el recolector de basura ). Se puede observar una mayor desaceleración en algunos casos específicos donde el código nativo puede beneficiarse de los códigos de operación adicionales proporcionados por la CPU, siendo el caso típico los cálculos sobre grandes enteros (por ejemplo, para RSA), porque la CPU puede ofrecer una multiplicación "extendida" (64x64- > 128) que el código Java no puede usar, debido a la falta de un tipo de entero de 128 bits en Java.
Para un experimento bastante completo en el contexto de las funciones hash (no "hashing de contraseña", simplemente "hashing"), consulte sphlib : una biblioteca que implementa muchas funciones hash, en C y en Java, con "esfuerzos similares en optimizaciones" (el mismo desarrollador para todo el lote), e incluye medidas en una variedad de tipos de plataformas .
Ahora, puede haber ralentizaciones adicionales para las aplicaciones de Android:
-
La CPU de un teléfono inteligente no es tan rápida como la de una PC. La CPU del teléfono inteligente puede ir al rango de gigahercios, pero aún así hacer menos trabajo por ciclo que la CPU x86, porque uno de los principales objetivos de una CPU de teléfono inteligente es ahorrar batería. Un teléfono inteligente debe estar activo durante un día completo, mientras participa en la actividad de la radio, mientras que una computadora portátil puede tener una batería más voluminosa y solo necesita estar encendida durante algunas horas. Los teléfonos inteligentes modernos son eficientes, pero todavía hay una brecha en comparación con la PC de escritorio. Digamos un factor 3x adicional.
-
Dalvik no es necesariamente el mejor compilador JIT del mundo. La relativa falta de músculo en bruto significa que el JIT no puede aplicar las estrategias de optimización más complejas, ya que haría la traducción JIT de un método demasiado costoso.
-
Hasta Android 2.1 (incluido), Dalvik no tiene JIT . Esta es la peor desaceleración, a la que aluden otras respuestas. En Android 2.1 (y antes), el bytecode de Java se interpreta, no se traduce a código nativo, y esto conlleva un alto costo adicional (por ejemplo, 10 a 20 veces más lento que el código JIT). Android 2.2 en adelante tiene JIT.
Cambiar a PBKDF2 no cambiará mucho la imagen. Si usa PBKDF2 , asegúrese de usar SHA-256 (o SHA-1), no SHA-512, porque la CPU del teléfono inteligente está basada en ARM y será bastante incómoda con las operaciones aritméticas de 64 bits en las que SHA-512 depende en gran medida, lo que ralentizará su código, mientras que el atacante tiene una PC, que realiza operaciones de 64 bits para el desayuno No incurrir en la misma desaceleración.
Resumen: bcrypt será muy lento en Android 2.1 (y versiones anteriores). Será algo rápido en Android 2.2, aunque no tan rápido como una PC (por ejemplo, entre 5 y 10 veces más lento). PBKDF2, scrypt ... no cambie esta imagen de manera significativa.
Todo esto se dice sobre el rendimiento de bcrypt. No hice ningún comentario sobre el uso correcto de los secretos derivados de bcrypt para la verificación de la contraseña y del cifrado. De hecho, cuando almacena "algo" para validar una contraseña, no hace que ese "algo" esté demasiado cerca de la clave derivada de la contraseña que utiliza para el cifrado.
Un "método criptográficamente razonable" es calcular el hash de contraseña con bcrypt o PBKDF2 (con sales e iteraciones y todo), y luego tomar la salida y expandirla con a Key Derivation Function en suficiente material clave para sus necesidades. En su contexto, tome la salida de bcrypt, luego cáscara con SHA-256. Esto produce 256 bits. Almacene los primeros 128 bits en su base de datos como "token de verificación de contraseña". Utilice la otra mitad como clave de cifrado.
PBKDF2 hace que este proceso sea un poco más sencillo ya que es un KDF, por lo que puede solicitar 256 bits de salida derivada de contraseña de inmediato, sin necesidad de un hashing adicional; mientras que el tamaño de salida de bcrypt se fija en 192 bits, lo que puede no ser suficiente para sus necesidades.