A principios de este año, me pidieron que evaluara el uso de JavaScript para cifrar la información confidencial en el navegador del usuario antes de enviarla a nuestro servidor. Si bien mi primera respuesta fue "preguntar a un experto", mi jefe se mostró inflexible, así que seguí adelante e investigué las opiniones de expertos sobre el tema lo mejor que pude. Basándome en esa investigación, le contesté con un rotundo "ningún experto piensa que es una buena idea" y pude convencerlo, pero no pude responder específicamente algunas de sus refutaciones por RAZONES, fue una mala idea. Específicamente, las principales razones que encontré para que el cifrado de JavaScript en el navegador fuera malo fueron:
- Solo use TLS en primer lugar, es 100% seguro que será mejor
- JavaScript no ofrece PRNG criptográficamente seguro
- Cualquier atacante Man-In-The-Middle simplemente modificaría el código de encriptación, haciéndolo inútil
Sin embargo, el caso de uso específico que estaba investigando mitigó esos:
- Ya estábamos planeando aplicar TLS, con la parte de JavaScript destinada a cubrir futuras vulnerabilidades de TLS
- Generaríamos un par de claves RSA en otra parte y enviaríamos la clave pública con el código de encriptación, en lugar de necesitar que el cliente genere o envíe sus propias claves
- Aunque no protegería contra un atacante que pudiera modificar nuestro javascript, todavía podríamos proteger contra vulnerabilidades que solo permiten LECTAR mensajes
No pude encontrar una respuesta real al último argumento en particular, y solo pude recurrir al "consenso abrumador". Puedo pensar en algunos argumentos POSIBLES, pero no fui capaz de apoyarlos definitivamente:
- El cifrado dentro de TLS no agrega ningún valor en primer lugar
- Las vulnerabilidades de solo lectura en TLS no son realistas, cualquier crack inherentemente permitiría la modificación también
- Incluso sin modificar el código de cifrado original, un atacante podría inyectar JavaScript de otra manera y evitar el cifrado de esa manera.
- Podría agregar una cantidad modesta de seguridad, pero el esfuerzo y el conocimiento requerido para crearlo y mantenerlo sería prohibitivo
TL; DR: Los principales argumentos que he visto contra el cifrado de JavaScript son 1) en su lugar, use TLS y 2) JavaScript no genera claves seguras. Si también se usa TLS y las claves se generan en otro lugar, ¿el cifrado de JavaScript comienza a agregar valor? '
Nota: En respuesta a un par de comentarios, el caso de uso aquí NO es un cifrado de extremo a extremo; el servidor necesita, al menos en algunas situaciones, leer los datos originales.