NOTA: Esta pregunta combinaba originalmente una "firma digital" y una "MAC", que desde entonces he aprendido que no son lo mismo. Cualquier referencia (en la respuesta o cualquier comentario) a una "firma" debe leerse como un "MAC".
Estoy experimentando con tokens de autenticación y estoy tratando de envolver mi mente en torno al mejor método.
Misiones
- Al iniciar sesión correctamente, se crea un token que contiene los usuarios
accountID, unnoncey unexpiry. Luego, el token se devuelve al cliente para usarlo en la próxima solicitud. - El cliente devuelve el token al servidor con cada solicitud para identificar el origen (
accountID) de cualquier solicitud dada. - El token contiene un nonce que se cambia con cada solicitud.
- Se crea un
MACa partir del valorplaintextpara garantizar que no se haya manipulado. - El valor
plaintextdel token (incluido elMAC) se cifra para garantizar que esté oculto de manera segura. - El cliente nunca está al tanto de
macKeyo deencryptionKey. No se pretende que el cliente tenga acceso al contenidoplaintextdel token.
Método actual
///process.env.TOKEN_ENCRYPTION_PASSWORD = '13sd4089f-268c-483d-9e82-jk3c1b47c77a';
///process.env.TOKEN_MAC_KEY = '1fde05f4-268c-483d-9e82-85fc1b42321';
/// Successful login by user ...
var token = {
nonce : 'SOME-UUID-GOES-HERE',
accountID : 'account-12345',
expires : 1234567890
};
token.mac = crypto.createHmac('sha512', TOKEN_MAC_KEY)
.update(JSON.stringify(token))
.digest('base64');
var encryptedToken = cryptoJS.AES.encrypt(JSON.stringify(token), TOKEN_ENCRYPTION_PASSWORD).toString();
response.send({
message : 'Created, MAC'd, and encrypted an auth token.',
authToken : encryptedToken
});
Preguntas
- ¿Es seguro, en este caso, emplear un método
MAC-then-encrypt? He leído varias opiniones sobre esto y me he ido más confundido que cuando comencé. - He leído que
cbc-modedebe usarse cuando se emplea un métodoMAC-then-encrypt. ¿Es este el modo predeterminado paraCryptoJS.AES.encrypt()? -
CryptoJS.AESparece bastante genérico. ¿Esta por defecto esAES256? ¿O es algo que debo declarar explícitamente en mi código? - Al pasar una cadena a
CryptoJS.AES.encrypt(), leí que genera automáticamente unkeyyiv'detrás de escena'. ¿Sería más seguro generar mis propioskeyyiv, o debería dejar queCryptoJSmaneje eso? - ¿Se puede tener más seguridad empleando un método
MAC-encrypt-MAC, o es simplemente agregando complejidad a la lógica de mi aplicación?