Este mensaje lo envía una parte (por ejemplo, el servidor) a la otra parte (por ejemplo, el cliente) para indicar que tiene un problema con los elementos criptográficos enviados por esa parte. Nominalmente , esto ocurre en las siguientes condiciones:
bad_record_mac
This alert is returned if a record is received with an incorrect
MAC. This alert also MUST be returned if an alert is sent because
a TLSCiphertext decrypted in an invalid way: either it wasn't an
even multiple of the block length, or its padding values, when
checked, weren't correct. This message is always fatal and should
never be observed in communication between proper implementations
(except when messages were corrupted in the network).
En el protocolo de enlace SSL / TLS, el primer mensaje cifrado enviado por cualquiera de las partes es el mensaje Finished
handshake que precede a los datos de la aplicación. Cuando el cifrado salió mal, esto se mostrará en ese punto, con la alerta bad_record_mac
.
Se debe tener en cuenta que cuando falla el intercambio de claves asimétricas, por ejemplo. Si el servidor intentó descifrar el "secreto maestro anterior" cifrado por RSA enviado por el cliente pero no encontró un mensaje RSA correctamente cifrado, entonces la mayoría de las implementaciones modernas del servidor continuarán con un secreto maestro previo al azar. Esta es una defensa contra ataques Bleichenbacher , que intentan obtener información adicional en el servidor privado clave al intentar adivinar si el descifrado falló en la etapa RSA o posterior. Para contrarrestar estos ataques, los servidores "retrasan" los errores hasta los mensajes Finished
, e intentarán realmente no explicar la causa exacta del error. Entonces, mientras que bad_record_mac
es nominalmente un problema con la capa de comprobación de integridad, estos errores tenderán a aparecer para cualquier problema relacionado con el cifrado.
Una causa plausible sería la siguiente: el cliente está utilizando una supuesta clave pública del servidor que no coincide con la clave privada del servidor real. Normalmente, el cliente extraerá la clave pública del servidor del certificado del servidor, que el servidor envía al cliente durante el protocolo de enlace. El servidor también posee una clave privada, que está vinculada matemáticamente con la clave pública. Si el servidor está configurado para usar el archivo incorrecto, podría obtener los síntomas que observa.
Le sugiero que use una herramienta de monitoreo de red (como Wireshark ) para observar los mensajes de intercambio: debería ver el Certificate
de mensaje del servidor, que contiene la cadena de certificados del servidor; para el primer certificado de esa cadena, puede extraer la clave pública del servidor, que el cliente utilizará. En el servidor, intente imprimir los detalles de la clave privada del servidor (si esto es fácil o no, depende del software involucrado y del almacenamiento de claves real), para ver si coinciden.
Otras posibles causas involucran implementaciones defectuosas de algunos algoritmos criptográficos (en el cliente y / o el servidor). La localización de estos errores puede ser difícil.
Para obtener más detalles de la depuración, también puede intentar conectarse al servidor con la herramienta de línea de comandos openssl
:
openssl s_client -connect theservername:443 -msg -debug
También intente jugar con algunas de las opciones para seleccionar la versión del protocolo ( -ssl2
, -ssl3
, -tls1
...) y los conjuntos de cifrado admitidos ( -ciphers
). En última instancia, incluso podría volver a compilar su propia versión de OpenSSL con un código de depuración personalizado insertado en él (para imprimir valores intermedios, etc.). OpenSSL es de código abierto, por lo que esto es técnicamente factible, si tiene algún conocimiento de programación en C
Un poco de dominio de los detalles del protocolo SSL ayudará. Consulte esta respuesta como punto de partida.