Responderé como desarrollador y diseñador de algunas adiciones a Crypto-API.
En primer lugar, Poncho tiene razón en que ninguna especificación de AES o modo de operación (como el BCE inseguro) indicará qué hacer en este caso. Es casi seguro que no propondrán el # 2 o el # 3, solo porque eso alteraría gravemente cualquier prueba de seguridad del algoritmo.
1. devolviendo un error?
La única respuesta correcta en mi opinión. AES solo acepta claves de 128, 192 o 256 bytes. Esto se llama una condición previa. El incumplimiento de una condición previa debe dar lugar a una falla. En Java, lo actualizaría rápidamente a RuntimeException
, ya que proporcionar menos bits para una clave simétrica siempre es un error de programación (no se espera que un usuario ingrese directamente una clave, y si es necesario ingresar una clave hexadecimal, necesita verificarlo antes ofreciéndolo a la API criptográfica).
El único lugar donde esta podría no ser la mejor respuesta es muy de API de bajo nivel donde solo se devuelve un puntero a una clave con un tamaño conocido. Pero los usuarios nunca deben llamar o incluso tener acceso a esa API de bajo nivel.
Devolver un error (o una excepción, para idiomas de nivel superior) también es fail-fast , lo que es una buena práctica de diseño de seguridad.
2. ¿Truncando la clave a 128 bits?
No, eso es horrible. No debe realizar una función criptográfica con menos datos relevantes para la seguridad que el proporcionado por el usuario. Usted estaría decidiendo por el usuario que menos seguridad es aceptable, algo que obviamente no es el rol de un diseñador de API.
Extender la clave con cero es igualmente horrible. Le está diciendo a su usuario que está utilizando AES-256, mientras que la seguridad real ofrecida es menor que eso (y posiblemente incluso cerca de cero).
Al igual que en (3), también fallará el principio de menos sorpresa .
Las funciones basadas en PHP mcrypt toman esta ruta y hay un flujo interminable de preguntas sobre SO que intenta replicar la funcionalidad de mcrypt en las API de criptografía bien comportadas.
3. ¿Tratar la clave como contraseña y usar alguna función KDF?
No. Si el usuario desea usar un KDF, ofrézcales un KDF. La ejecución de un KDF en un modo de cifrado para AES viola todo tipo de principios de diseño, incluido el principio de menos sorpresa . Una API de AES debería hacer eso: ofrecer una interfaz de cifrado para obtener confidencialidad. Una API podría hacer que sea fácil utilizar un KDF, pero no debería elegir un KDF y un conjunto de parámetros, y hacerlo un valor predeterminado (que en ese momento parece seguro, y nunca se puede cambiar después).
Hay muchos usuarios de la API CryptoJS que confunden la rutina de encriptación que usa una contraseña con la que usa una clave, simplemente porque tienen el mismo nombre.
Notas:
- Algunas API de Crypto como Java no aceptan directamente una clave binaria. La clave primero debe ser generada a partir de los bytes. Una razón para no usar bytes directamente como clave es que los dispositivos de hardware (HSM, tarjetas inteligentes) ni siquiera pueden exponer los bytes al software en primer lugar. En ese caso, el error puede ser lanzado de antemano, dependiendo de la implementación.