Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues decoding with PHP OpenSSL generated private key #37

Open
markharding opened this issue Dec 16, 2014 · 1 comment
Open

Issues decoding with PHP OpenSSL generated private key #37

markharding opened this issue Dec 16, 2014 · 1 comment

Comments

@markharding
Copy link

Encryption works fine, and I can decrypt again in PHP using the private key. However, using a PHP5.5 private key, I'm unable to decrypt with JSEncrypt. PHP 5.4 generated private keys on my mac is able to decrypt with JSEncrypt however.

I do notice that the key no longer included RSA on the failing private keys (http://php.net/manual/en/function.openssl-pkey-export.php#101839)

Example Public Key:

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtCllajSev6wdWy29Ow2l
28S0jZnVmnOsAzAa3bIWfeH54PbBcP0+799jR4Y8mHXcdyx229AKVpNr8nb30iwH
4w2PcG6EC1ozCw3J0Wc+jtIJkl97rFF3t2Zg34Jl2hrfdb29fb36WS5bMwII/ONN
XP1o7RBda/MOt4kl9dJE5CTQUW/x5Db44a1EFD3P8sKFWPlwCqs7KEGNmvPSvteO
UdCLNRyd8W1ORngrZ3agoDp8B0mwIzZnzVlS08Z7j66rLTrIitVDHc0o40jKm58i
GPBsrV9PXxz9DrNSkruIXmrziZuwdBX3ucTZXgu+anNdzCRcMET2tOgpO8mUtpwL
NYsDpyGZ89eta0nsxAQe9jcn2PEDl32HujaMyU8yVth/JhLXOW5pODi+KPfwCL2g
S6ZE1LPUkcsmuhozLT5ePVswRNYOO8DcFc63k4oV0ZuRiXpTzGBquzU6MeLoCkJm
wWAdtVD81H6fPeMvA7pWmFauTn847M8FjWOa2/50PFXjjs+qnq5N58/hRWTZpGXu
ZIw8uIQXqjViVjDagtcFJEQ9QQJw0CE0TNqd9TZs3y9yr3vDvshMjDtacGLXMRFb
DszWWCp9pUpBDrDf/vIbXUpkufdtuVdJTIrQDDZ2Su/sG/dRu0R7MbtDiDTucuch
6TxLNI1mQkwQmZ0XL/Az9vMCAwEAAQ==
-----END PUBLIC KEY-----

Example Private Key:

-----BEGIN PRIVATE KEY-----
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
Yqa08FSwsgK2GOEUJU4tx/m28a1lXA==
-----END PRIVATE KEY-----

Example of 'testing' encrypted:

UZ7xDUgPk06BIT1M3PFGlTN8h2iOJvwJl0MO8NkklkhfK6zsxgz25FQLRa37FcyPSSz3w/+HbUm1YQy0Kdg3DQsPYr8aNtTIZ5FyQlqoUZwViSEdAqrgtUFdcxWSTf6yaQsRjSsSGUz4UHh/rFt1shrUN9MJ1O+e0Gml9ySLhwffUz6vvReE0avbZXT/GbkwitxvcWTL3xTKM19U6mvTB/+vHse3HyrbNKxDqVzn7a10N+ZcxmQpVjf4uC8U5dQtkkCBVcexdY0vVqps62Ilw8cNLGD0MLejs0ypMgB9lMklInIYigvP45sgnEgs4tsKXio72kW/2LVN6c0EUtAhkrFIk9LY1cUVov/swEJ658GxKS088LWW+xLZz49rOdM6BPFrcdw2CCLxbbrCTF+wxm5tTKFKVW+Z3xSBX9tBTkj1ZiO9rIGLLUEX6QGFSy/BIEPOaxnKRExr92CD2Dg9mRgGJbGntYiaz07Pa89ciURkCEQssyZFqnCaLt2k9+0dXKWNr8N4dQr3v+GBPNZbKW7EGXNX1tRiLThiS+BHSBkcdgZD+RLtWEVg/mWogh9Ukg9Qz5/JZyRQt4r+4uFHCFcteiauS1qHWZxuLPRTHXeCRnpmRiY2bPeIscwMk8a2h5yrYeIgMrchzFKqRXsybjpyLFiSUiydLVR+t4bMzUY=

I've attempted multiple key lengths etc but that makes no difference.

SSL VERSIONS:

WORKS WITH: OpenSSL 0.9.8za 5 Jun 2014
FAILS WITH: OpenSSL 1.0.1f 6 Jan 2014

zoloft added a commit that referenced this issue Jan 26, 2015
resolves issue with OpenSSL private keys #37
@gramo44
Copy link

gramo44 commented Oct 26, 2017

Maybe my solution clarifies this issue

The only problem I have is when I send a long text.

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, after that jsencrypt returns false.

If I use private_key_bits of 512 I can send
"José compró en Perú una vieja zampoña. Excusánd"
nothing longer, after that jsencrypt returns false.

I don't know why is that. It seems that the size of the data jsencrypt can send depends on the size of the key.

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

If someone find how to fix I'll appreciate a lot that information

My working code is as follows:

<?php
    //------------------------------------------------------------
    // Global Settings.
    //------------------------------------------------------------
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    $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'
                src='https://ajax.googleapis.com/ajax/libs/".
                    "jquery/3.2.1/jquery.min.js'></script>
        <script type='text/javascript'
                src='lib/jsencrypt.js'></script>
        ";

    $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;'>".
        $pubKey_html.
        "</textarea>
        <script type='text/javascript'>
            $('#ENVIAR').click(function () {
                var codificador = new JSEncrypt();
                codificador.setKey($('#pubkey').val());
                var cifrado = codificador.encrypt($('#mensaje').val());
                window.open('?mensaje=' + encodeURIComponent(cifrado)
                           , '_top');
            });
        </script>
        ";

    //------------------------------------------------------------
    // 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>
            ".$descifrado."
            ";
    }

    //------------------------------------------------------------
    // HTML DISPLAY
    //------------------------------------------------------------
    $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 {
            //------------------------------------------------------------
            // CARGA DE LLAVES RSA ARCHIVADAS
            //------------------------------------------------------------
            $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) {
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // PROPÓSITO:
    // 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);
        openssl_free_key($llavePrivadaCruda);

        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;
    }

?>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants