Solución:
Como señalaba en un comentario a su pregunta, el vector de ataque que está contemplando (servidor comprometido) implica que es probable que JavaScript también se vea comprometido, en cuyo caso no se debe confiar en el código JavaScript que se ejecuta en el cliente. de todas formas. (Sería bastante fácil hacer que JavaScript envíe los datos descifrados al servidor con una solicitud asincrónica en segundo plano: nuevamente, dado que el servidor estaría bajo el control del atacante, no habría necesidad de trucos para eludir el mismo -políticas de origen allí.)
Sugeriría seguir la ruta de una aplicación independiente (como Java WebStart), quizás firmada (con una clave privada que no se encuentra en el servidor).
Si aún está dispuesto a seguir adelante con este tipo de arquitectura, evite liberar la clave privada del usuario en JavaScript a toda costa. Esto podría comprometer la clave privada del usuario, no solo los datos cifrados.
Cuando usa una clave privada en su navegador para la autenticación de certificado de cliente SSL / TLS, la clave privada no está expuesta a ningún código utilizado por el servidor. El navegador lo usa para el protocolo de enlace y el servidor obtiene el certificado (que es público), pero la clave privada no se acerca a lo que puede ver el código HTML + JS. (De hecho, en OSX con Safari, la clave privada es utilizada por la biblioteca SSL / TLS subyacente y ni siquiera está expuesta al proceso del usuario).
Las bibliotecas de JavaScript para RSA que he visto requieren el uso directo de la clave privada, es decir, deben poder usar el exponente privado directamente. Claramente, eso no es bueno si se encuentra en una situación en la que no puede confiar en el servidor.
Ser capaz de usar una clave privada dentro del navegador para operaciones RSA, sin permitir que el script se apodere del material privado en sí, requeriría una integración más estrecha con el navegador, en particular, alguna API para firmar y descifrar que usaría estas funciones directamente en el mecanismo de seguridad del navegador, sin exponer el material de la clave privada (en general, un enfoque similar al que ofrece PKCS # 11 a las aplicaciones que lo utilizan).
Hasta donde yo sé, la API de JavaScript de cifrado de Mozilla actual no proporciona funciones para descifrar / firmar usando los navegadores (es solo para la solicitud de certificado y la generación de claves). Sin embargo, parece que hay planes para hacer esto:
- https://wiki.mozilla.org/Privacy/Features/DOMCryptAPISpec/Latest
- http://mozilla.ddahl.com/domcrypt/demos/demo.html
En la plataforma de IE, CAPICOM debería haber sido de interés, pero parece estar desaprobado hoy en día.