¿Debo agregar una firma sha256 a un token encriptado AES_256_CBC?

0

actualmente genero un token para una aplicación móvil de la siguiente manera. Descifro el token para procesar la solicitud y evaluar si el usuario ha iniciado sesión. Estoy en la conexión TLS RSA 2048 bits. Me preguntaba si $ GLOBALS es seguro y si agregar un hmac_sha256 haría que mi token fuera más difícil de falsificar o no cambiaría mucho.

$GLOBALS['encryption_key'] = <<<'EOT'
 MIGsAgEAAiEAwtvvzQzXiesVUPxXV7+jvUbmXfavBqxdakC1Tn+PpmcCAwEAAQIg
 WtklzWkOWKv0zURJCI09riGVIPIzGx1XPmFVaAbOeBECEQDynUX9BuIv3k6IA1wm
 IcSpAhEAzZwpEHQtbj3xpiWy34/sjwIRAJ2ltmmxBF6obI0S6djZTmkCEQDLpv5h
 hsEs7Xv5lmOK3lJvAhEAxJzS4NEgH2fF7mfaLfIWWg==
 EOT;

function new_auth_token($user) {
  $token_data = [
      'param1'   => 'type',
      'param2'   => $user['p2'],
      'param3'   => $user['p3'],
      'param4'   => $user['p4'],
      'param5'   => $user['p5'],
      'expedite' => (time() + (3600*24*180))
  ];
  $json  = json_encode($token_data);
  $iv    = openssl_random_pseudo_bytes(openssl_cipher_iv_length(AES_256_CBC));
  $ssl   = openssl_encrypt($json, AES_256_CBC, $GLOBALS['encryption_key'], 0, $iv);
  $token = base64_encode($ssl).'.'.base64_encode($iv);
  return $token;
}
    
pregunta Nicolas Manzini 28.10.2015 - 19:53
fuente

2 respuestas

2

Debe autenticar el texto cifrado porque el cifrado es maleable. La mejor manera es usar un AEAD. Si no puede hacer eso, debe usar hmac-sha256 con una clave que debe permanecer secreta pero debe ser diferente de la clave AES. Debe aplicar MAC el IV y el texto cifrado después de cifrar y almacenar el resultado en el token (como cuando almacena el IV). Debe comprobar el MAC antes de intentar descifrar el texto cifrado. Debe utilizar una función de comparación de tiempo constante para verificar el MAC.

De lo contrario, las personas pueden descifrar mensajes, mensajes falsos, tal vez extraer la clave AES.

¿Observa todos los "mostos"? Es fácil estropearlo. Deberías preferir una api de nivel superior que lo haga bien y no te permita hacerlo mal. Prueba libsodium.

EDIT

Notas sobre su código:

Su "clave de cifrado" AES es una clave privada RSA. Usted sabe que las claves RSA no son claves AES, ¿verdad? Además, RSA de 256 bits es completamente inútil, roto en minutos en una computadora portátil. Por cierto, ahora que ha publicado la clave RSA, no puede usarla para nada real, incluso si solía ser una clave segura (las claves RSA con módulo de 2048 bits y más son seguras).

Las claves AES-256 son matrices de bytes de 32 bytes de longitud. En base64 eso sería 45 bytes. Debe descodificar la base64 antes de usar la cadena en el cifrado o descifrado. Puedes generar claves AES fuertes como: head -c32 /dev/urandom | base64 .

Deberías usar una biblioteca con una API que no te permita pasar una cadena con una supuesta clave AES que tiene la longitud incorrecta.

En conclusión, deberías leer mucho más sobre crypto antes de intentar usarlo con la información confidencial de alguien.

    
respondido por el Z.T. 28.10.2015 - 20:33
fuente
0

Presiona el hash sha de tu token al cliente y registra el token en una sesión u otro mecanismo de almacenamiento de memoria persistente.

En cada solicitud, el cliente enviaría el hash sha del token nuevamente al servidor, momento en el que el token cifrado correspondiente podría ser hash, revalidado, descifrado y verificado para los permisos, etc.

Ese sería el tiempo de desarrollo más fácil para mí, etc.

Dependiendo del nivel de seguridad que desee implementar, la respuesta de otros carteles con respecto a las firmas digitales y / o hmac del token es otra ruta.

Debería descartar todo e investigar soluciones existentes como oAuth (recomendaría la versión 1 de la especificación si está totalmente decidido a utilizar primitivos criptográficos).

    
respondido por el jas- 29.10.2015 - 03:55
fuente

Lea otras preguntas en las etiquetas