RSA encryption/decryption compatible with Javascript and PHP

I'd like to encrypt in Javascript and then decrypt in PHP. There are RSA implementations for Javascript and PHP but they are not compatible. I cannot decrypt in PHP correctly what I had encrypted with Javascript.

Does anyone know a library/code that will work both with Javascript and PHP?




Here is an JavaScript RSA encryption library:

And I think you could use something like this class to decrypt the generated encrypted string -

Let me know if you manage get this work together, as I am myself looking into this subject (I actually found this post looking for this answer myself :P ) .

Edit: Look, I've also found this - - seems related to the previous two as well...


Try the following simple example.

It is using a open source javascript library


<script language="JavaScript" type="text/javascript" src="jsbn.js"></script>
<script language="JavaScript" type="text/javascript" src="rsa.js"></script>

<script language="JavaScript">

    function encryptData(){

        //Don't forget to escape the lines:
        var pem="-----BEGIN PUBLIC KEY-----\
-----END PUBLIC KEY-----";

        var key = RSA.getPublicKey(pem);

        element.value=RSA.encrypt(element.value, key);

<form method='POST' id='txtAuth' onsubmit='encryptData()'>
    <input type='text' name='username'/>
    <input type='password' name='password' id='password' placeholder="password"/>
    <input name='submit' type='submit' value='Submit'>



if (isset($_POST['password'])) {

    //Load private key:
    $private = "-----BEGIN RSA PRIVATE KEY-----
    -----END RSA PRIVATE KEY-----";
    if (!$privateKey = openssl_pkey_get_private($private)) die('Loading Private Key failed');

    $decrypted_text = "";
    if (!openssl_private_decrypt(base64_decode($_POST['password']), $decrypted_text, $privateKey)) die('Failed to decrypt data');

    //Decrypted :) 

    //Free key



If you set up your server to use SSL then you can have encrypted transmission via ajax using https. That is probably the best way to encrypt data between javascript and php. If you want to make it yourself there is a big chance you will screw up somewhere and the system wont be secure.

Google on how to set up https for your server.


I assume you have a valid reason to do that other than to do https yourself, so I'd say that if you stick to the standards you should be able to easily decrypt with whatever technology supports these standards : ie it should work

For example if you encrypt your data in PKCS#7 format, be sure that your php library knows that the input data is PKCS#7.

Also be sure that your encryption key is not scrambled between server and client. Did you try to decrypt your data with your javascript library ?

Hope this can help...


Maybe you can help by putting the code you're using for both js and php.

Also, maybe you could be more specific on why you need to use js and php. Maybe you could use only php, and AJAX (to query the same php function) where you were using js.


I am not one to toot my own horn but I have a project at that will perform this functionality.

A private key is generated on the server, a public key and pkcs#7 certificate is also derived from the private key. The public key is sent to the client at which time each form element assocated with the specified form is encrypted prior to being submitted to the server.

It is 100% OpenSSL compatibile as it uses the PHP OpenSSL extension to generate, encrypt and decrypt data.

This project is not as secure as PGP because the JavaScript will not sign and encrypt emails until the form data is sent to the server, but the form data that is to be encrypted and or signed is encrypted using RSA public key encryption prior to being sent to the server.

Again the project is not complete in terms of the authentication and email signing but for ordinary form encryption using a public key it works very well.


I find this jsencrypt library (, after 2 days trying I got my solution.

The only problem I got is when I send a long text. That's because RSA, by definition, supports strings of limited lenght.

RSA, as defined by PKCS#1, encrypts "messages" of limited size. With the commonly used "v1.5 padding" and a 2048-bit RSA key, the maximum size of data which can be encrypted with RSA is 245 bytes. No more.

i.e. If I use private_key_bits of 1024 I can send

"José compró en Perú una vieja zampoña. Excusándose, Sofía tiró su whisky al desagüe de la banqueta."

nothing longer. If I use private_key_bits of 512 I can send

"José compró en Perú una vieja zampoña. Excusánd"

nothing longer.

On long strings JavaScript console reports: "Message too long for RSA"

Then if you want to encrypt long strings you must compress and split them before javascript encryption and after decryption join and uncompress on php, I think zlib is a good solution for split/join because it is supported on javascript and php.

My working code is as follows:

    // Global Settings.
    ini_set('display_errors', 1);
    $directorio = "/path/to/key/directory/apache/writable/";
    $nombre_base = "llaves_php";

    // Initialization.
    $encabezado_html = "";
    $cuerpo_html = "";

    // Loading keys
    list($privateKey, $pubKey) =
        cargar_llaves_RSA($directorio, $nombre_base);

    // Form that uses javascript to encrypt data.
    // (it uses only the public key)
    $librerias_html = "
        <script type='text/javascript'
        <script type='text/javascript'

    $pubKey_html = htmlentities($pubKey);
    $datos_html = "
        <h2>Cifrando con Javascript</h2>
        <input type='text' id='mensaje' />
        <br />
        <button id='ENVIAR'>Enviar</button>
        <br />
        <textarea id='pubkey' style='display: none;'>".
        <script type='text/javascript'>
            $('#ENVIAR').click(function () {
                var codificador = new JSEncrypt();
                var cifrado = codificador.encrypt($('#mensaje').val());
      '?mensaje=' + encodeURIComponent(cifrado)
                           , '_top');

    // Decrypting using php (it uses only the privateKey)
    if (isset($_REQUEST['mensaje'])) {
        openssl_private_decrypt( base64_decode($_REQUEST['mensaje'])
                               , $descifrado
                               , $privateKey);
        $datos_html.= "
            <h2>Descifrando con PHP</h2>

    $encabezado_html.= "<title>Receptor de mensaje cifrado</title>"
                     . $librerias_html;

    $cuerpo_html.= $datos_html;

    $contenido = "<head>$encabezado_html</head><body>$cuerpo_html</body>";
    $contenido = "<html>$contenido</html>";
    print $contenido;

// Functions

    function cargar_llaves_RSA($directorio, $nombre_base) {
    // PROPÓSITO: Genera o carga desde archivos las llaves RSA
    // ENTRADAS:
    // $directorio: Directorio donde se encuentran los archivos.
    // $nombre_base: Nombre, sin extensión, de los archivos con
    //               las llaves.
    // SALIDAS:
        if (  !file_exists($directorio.$nombre_base.".crt")
           || !file_exists($directorio.$nombre_base.".pub")) {
            list($privateKey, $pubKey) = crear_llaves_RSA($directorio.$nombre_base);
        } else {
            $privateKey = file_get_contents($directorio.$nombre_base.".crt");
        if (!$privKey = openssl_pkey_get_private($privateKey))
            die('Loading Private Key failed');
            $pubKey  = file_get_contents($directorio.$nombre_base.".pub");

    return array($privateKey, $pubKey);

    function crear_llaves_RSA($ruta_base) {
    // generacion de llaves RSA en php
    // ENTRADAS:
    // $ruta_base: Ruta de los archivos a generar sin extensión.
    // SALIDAS:
    // Se generarán dos archivos, uno con la llave privada con
    // extensión .crt, el otro con llave pública con extensión
    // .pub; la función retorna tanto la llave pública como la
    // privada en un arreglo.
        $config = array(
            "private_key_bits" => 1024,
            "private_key_type" => OPENSSL_KEYTYPE_RSA,

        $llavePrivadaCruda = openssl_pkey_new($config);
        openssl_pkey_export_to_file($llavePrivadaCruda, $ruta_base.".crt");
        $privateKey = file_get_contents($ruta_base.".crt");
        openssl_pkey_export($llavePrivadaCruda, $privKey);

        $pubKeyData = openssl_pkey_get_details($llavePrivadaCruda);
        $pubKey = $pubKeyData["key"];
        file_put_contents($ruta_base.".pub", $pubKey);

    return array($privateKey, $pubKey);

    function Mostrar($valor) {
    // PROPÓSITO: Genera el código HTML para presentar una
    // variable embebida en la página.
    // ENTRADAS:
    // $valor: el valor a presentar.
    // SALIDAS: código html que permite visualizar la variable.
        $retorno = htmlentities(stripslashes(var_export($valor, true)));
        $retorno = "<pre>$retorno</pre>";
        return $retorno;


Directory tree must looks like:

??? script.php
??? lib
    ??? jsencrypt.js

and a directory writable by php outside of public zone named



Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.