2009-03-04 17 views
7

Vorrei crittografare in Javascript e quindi decifrare in PHP. Esistono implementazioni RSA per Javascript e PHP ma non sono compatibili. Non riesco a decifrare correttamente in PHP ciò che avevo crittografato con Javascript.Codifica/decodifica RSA compatibile con Javascript e PHP

Qualcuno conosce una libreria/codice che funzionerà sia con Javascript che con PHP?

Grazie.

+1

Sembra che tu stia considerando questo per la crittografia di dati sensibili tra un client e un server. Sei avvisato che questo NON offrirà NESSUNA sicurezza contro un attacco man-in-the-middle in cui qualsiasi dato di passaggio sarà compromesso. Utilizza HTTPS per crittografia end-to-end sicura e autenticata. – deed02392

risposta

1

Se si imposta il server per utilizzare SSL, è possibile avere la trasmissione crittografata tramite ajax utilizzando https. Questo è probabilmente il modo migliore per crittografare i dati tra javascript e php. Se vuoi farlo da solo, c'è una grande possibilità che ti rovini da qualche parte e il sistema non sarà sicuro.

Google su come impostare https per il server.

0

Suppongo che tu abbia una valida ragione per farlo oltre a fare https te stesso, quindi direi che se ti attieni agli standard dovresti essere in grado di decifrare facilmente con qualsiasi tecnologia supporti questi standard: cioè dovrebbe lavoro

Ad esempio se si crittografa i dati nel formato PKCS # 7, assicurarsi che la propria libreria php sappia che i dati di input sono PKCS # 7.

Accertarsi inoltre che la chiave di crittografia non sia codificata tra server e client. Hai provato a decrittografare i tuoi dati con la tua libreria javascript?

Spero che questo può aiutare ...

0

Forse si può aiutare mettendo il codice che si sta utilizzando per entrambi i js e PHP.

Inoltre, potresti essere più specifico sul motivo per cui devi utilizzare js e php. Forse potresti usare solo php e AJAX (per interrogare la stessa funzione php) dove stavi usando js.

+0

Penso che l'OP stia cercando di inviare qualcosa come una password al server in forma crittografata. Se invii la password ad una funzione php usando AJAX, invierai comunque la password in chiaro alla chiamata AJAX e quindi la crittografia nel metodo php non avrebbe più senso – lugte098

7

Ecco una libreria di crittografia JavaScript RSA: http://www.ohdave.com/rsa/

e penso che si potrebbe usare qualcosa di simile a questa classe per decifrare la stringa cifrata generata - http://www.phpclasses.org/browse/package/4121.html

Fatemi sapere se si riesce ottenere questo lavoro insieme, come sono io stesso a esaminare questo argomento (in realtà ho trovato questo post cercando questa risposta personalmente: P).

Edit: Guarda, ho trovato anche questo - http://www.sematopia.com/?p=275 - sembra per il precedente due pure ...

0

Io non sono uno a toot il mio proprio corno ma ho un progetto a github.com che eseguirà questa funzionalità.

Una chiave privata viene generata sul server, una chiave pubblica e un certificato pkcs # 7 derivano anche dalla chiave privata. La chiave pubblica viene inviata al client e in quel momento ogni elemento del modulo associato al modulo specificato viene crittografato prima di essere inviato al server.

È OpenSSL compatibile al 100% poiché utilizza l'estensione PHP OpenSSL per generare, crittografare e decrittografare i dati.

https://github.com/jas-/jQuery.pidCrypt/

Questo progetto non è sicuro come PGP, perché il JavaScript non firmare e crittografare le email fino a quando i dati del modulo viene inviato al server, ma i dati del modulo che deve essere criptato e o firmato è cifrato utilizzando la crittografia a chiave pubblica RSA prima di essere inviata al server.

Anche in questo caso il progetto non è completo in termini di autenticazione e firma della posta elettronica, ma per la normale crittografia dei moduli mediante una chiave pubblica funziona molto bene.

5

Provare il seguente semplice esempio.

Si sta usando una open source libreria javascript https://github.com/ziyan/javascript-rsa

HTML/JavaScript:

<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-----\ 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfmlc2EgrdhvakQApmLCDOgP0n\ 
NERInBheMh7J/r5aU8PUAIpGXET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t\ 
6rF4sYqV5Lj9t32ELbh2VNbE/7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaA\ 
U8bTnLEPMNC1h3qcUQIDAQAB\ 
-----END PUBLIC KEY-----"; 

     var key = RSA.getPublicKey(pem); 

     element=document.getElementById('password'); 
     element.value=RSA.encrypt(element.value, key); 
    } 
</script> 

<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'> 
</form> 

PHP:

<?php 

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

    //Load private key: 
    $private = "-----BEGIN RSA PRIVATE KEY----- 
    MIICXAIBAAKBgQDfmlc2EgrdhvakQApmLCDOgP0nNERInBheMh7J/r5aU8PUAIpG 
    XET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t6rF4sYqV5Lj9t32ELbh2VNbE 
    /7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaAU8bTnLEPMNC1h3qcUQIDAQAB 
    AoGAcbh6UFqewgnpGKIlZ89bpAsANVckv1T8I7QT6qGvyBrABut7Z8t3oEE5r1yX 
    UPGcOtkoRniM1h276ex9VtoGr09sUn7duoLiEsp8aip7p7SB3X6XXWJ9K733co6C 
    dpXotfO0zMnv8l3O9h4pHrrBkmWDBEKbUeuE9Zz7uy6mFAECQQDygylLjzX+2rvm 
    FYd5ejSaLEeK17AiuT29LNPRHWLu6a0zl923299FCyHLasFgbeuLRCW0LMCs2SKE 
    Y+cIWMSRAkEA7AnzWjby8j8efjvUwIWh/L5YJyWlSgYKlR0zdgKxxUy9+i1MGRkn 
    m81NLYza4JLvb8/qjUtvw92Zcppxb7E7wQJAIuQWC+X12c30nLzaOfMIIGpgfKxd 
    jhFivZX2f66frkn2fmbKIorCy7c3TIH2gn4uFmJenlaV/ghbe/q3oa7L0QJAFP19 
    ipRAXpKGX6tqbAR2N0emBzUt0btfzYrfPKtYq7b7XfgRQFogT5aeOmLARCBM8qCG 
    tzHyKnTWZH6ff9M/AQJBAIToUPachXPhDyOpDBcBliRNsowZcw4Yln8CnLqgS9H5 
    Ya8iBJilFm2UlcXfpUOk9bhBTbgFp+Bv6BZ2Alag7pY= 
    -----END RSA PRIVATE KEY-----"; 
    if (!$privateKey = openssl_pkey_get_private($private)) die('Loading Private Key failed'); 

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

    //Decrypted :) 
    var_dump($decrypted_text); 

    //Free key 
    openssl_free_key($privateKey); 
} 
?> 

Enjoy!

+1

Per i futuri lettori: David.Ask suggerito in una modifica rifiutata a questa risposta che questo dovrebbe essere aggiunto in testa: '' – Tieme

+0

Utilizzare questo progetto con PHP anwser funziona come un fascino per me https://github.com/travist/jsencrypt/ –

0

Trovo questa libreria jsencrypt (http://travistidwell.com/jsencrypt), dopo 2 giorni di tentativi ho ottenuto la mia soluzione.

L'unico problema che ho riscontrato è quando invio un lungo testo. Questo perché RSA, per definizione, supporta stringhe di lunghezza limitata.

https://security.stackexchange.com/questions/33434/rsa-maximum-bytes-to-encrypt-comparison-to-aes-in-terms-of-security/33445#33445

RSA, come definito dal PKCS # 1, cripta "messaggi" di dimensioni limitate. Con il "padding v1.5" comunemente usato e una chiave RSA a 2048 bit, la dimensione massima dei dati che possono essere crittografati con RSA è di 245 byte, la massima dimensione di . Non piu.

cioè Se uso private_key_bits di 1024 posso inviare

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

nulla più. Se uso private_key_bits di 512 posso inviare

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

nulla più.

Su lunghe stringhe JavaScript console riferisce: "Messaggio troppo lungo per RSA"

Poi, se si desidera crittografare stringhe lunghe è necessario comprimere e dividerli prima javascript crittografia e dopo la decrittografia unisco e decomprimere il php, credo zlib è una buona soluzione per split/join perché è supportato su javascript e php.

Il mio codice di lavoro è la seguente: must albero

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

?> 

Directory assomiglia:

├── script.php 
└── lib 
    └── jsencrypt.js 

e una directory scrivibile da PHP al di fuori della zona di pubblico denominato

/path/to/key/directory/apache/writable/ 

Problemi correlati