2009-03-04 8 views
7

Chciałbym zaszyfrować w JavaScript, a następnie odszyfrować w PHP. Istnieją implementacje RSA dla JavaScript i PHP, ale nie są one kompatybilne. Nie mogę odszyfrować w PHP poprawnie tego, co zaszyfrowałem przy pomocy Javascript.Szyfrowanie/deszyfrowanie RSA zgodne z Javascript i PHP

Czy ktoś wie, biblioteka/kod, który będzie działać zarówno z JavaScript i PHP?

Dzięki.

+1

Wygląda na to, że rozważasz to do szyfrowania poufnych danych między klientem a serwerem. Zostajesz ostrzeżony, że NIE zaoferuje to JAKIEGOKOLWIEK zabezpieczenia przed atakiem typu "man-in-the-middle", w którym przechwycone dane zostaną naruszone. Użyj protokołu HTTPS do bezpiecznego, uwierzytelnionego szyfrowania od końca do końca. – deed02392

Odpowiedz

1

Jeśli skonfigurowałeś serwer do korzystania z SSL, możesz mieć szyfrowaną transmisję przez ajax używając https. Jest to prawdopodobnie najlepszy sposób szyfrowania danych między javascript i php. Jeśli chcesz zrobić to sam, istnieje spora szansa, że ​​coś zgubisz, a system nie będzie bezpieczny.

Google, jak skonfigurować https dla swojego serwera.

0

Zakładam, że masz uzasadniony powód, by zrobić to inaczej niż zrobić to samemu https, więc powiedziałbym, że jeśli przestrzegasz standardów, powinieneś być w stanie łatwo odszyfrować każdą technologię, która obsługuje te standardy: praca

Na przykład, jeśli zaszyfrujesz dane w formacie PKCS # 7, upewnij się, że biblioteka php wie, że dane wejściowe to PKCS # 7.

Upewnij się również, że klucz szyfrowania nie jest kodowany między serwerem a klientem. Czy próbowałeś odszyfrować swoje dane za pomocą biblioteki javascript?

nadzieję, że może pomóc ...

0

Może pomóc poprzez wprowadzenie kodu używasz zarówno dla js i php.

Być może możesz być bardziej szczegółowy, dlaczego musisz używać js i php. Być może mógłbyś użyć tylko php i AJAX (aby zapytać o tę samą funkcję php), w której używasz js.

+0

Myślę, że OP próbuje wysłać coś w postaci hasła do serwera w postaci zaszyfrowanej. Jeśli wyślesz hasło do funkcji php za pomocą AJAX, to nadal będziesz wysyłać hasło w postaci zwykłego tekstu do wywołania AJAX, a następnie zaszyfrowanie go w metodzie php nie ma już sensu. – lugte098

7

Oto biblioteki szyfrowania JavaScript RSA: http://www.ohdave.com/rsa/

I myślę, że można użyć coś jak tej klasy odszyfrować wygenerowany zaszyfrowany ciąg - http://www.phpclasses.org/browse/package/4121.html

Daj mi znać, jeśli uda się tę pracę razem, ponieważ sam się zajmuję tym tematem (faktycznie znalazłem ten post samemu szukając odpowiedzi: P).

Edit: Spójrz, ja również to - http://www.sematopia.com/?p=275 - wydaje się podobne do dwóch poprzednich, a także ...

0

Nie należę do trąbienie własne róg ale mam projekt w github.com który wykona tę funkcję.

Klucz prywatny jest generowany na serwerze, klucz publiczny i certyfikat pkcs # 7 również pochodzi z klucza prywatnego. Klucz publiczny jest wysyłany do klienta, w którym to czasie każdy element formularza zaimplementowany w określonym formularzu jest szyfrowany przed przesłaniem go na serwer.

Jest kompatybilny w 100% z OpenSSL, ponieważ wykorzystuje rozszerzenie PHP OpenSSL do generowania, szyfrowania i odszyfrowywania danych.

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

Ten projekt nie jest tak bezpieczne, jak PGP, ponieważ JavaScript nie będzie podpisywanie i szyfrowanie wiadomości e-mail, dopóki dane formularz jest przesyłany do serwera, ale dane formularza, który ma być szyfrowane i lub podpisane są szyfrowane za pomocą szyfrowania kluczem publicznym RSA przed wysłaniem na serwer.

Ponownie projekt nie jest kompletny pod względem uwierzytelniania i podpisywania wiadomości e-mail, ale w przypadku zwykłego szyfrowania formularzy za pomocą klucza publicznego działa bardzo dobrze.

5

Spróbuj następującego prostego przykładu.

jest za pomocą open source biblioteki 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

Dla przyszłych czytelników: David.Ask zasugerował w odrzuconej edycji tej odpowiedzi, że należy to również dodać do nagłówka: '' – Tieme

+0

Użyj tego projektu w PHP anwser działa jak urok dla mnie https://github.com/travist/jsencrypt/ –

0

Znajduję tę bibliotekę jsencrypt (http://travistidwell.com/jsencrypt), po 2 dniach próbuję dostałem moje rozwiązanie.

Jedyny problem jaki mam, to wysyłanie długiego tekstu. To dlatego, że RSA, z definicji, obsługuje łańcuchy o ograniczonej długości.

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

RSA, zdefiniowane przez PKCS # 1, szyfruje "Wiadomości" o ograniczonym rozmiarze. Z powszechnie używaną "dopełnieniem v1.5" i kluczem RSA 2048-bitowym, , maksymalny rozmiar danych , który może być zaszyfrowany za pomocą RSA, wynosi 245 bajtów. Już nie.

tj Jeśli używam private_key_bits 1024. Mogę wysłać

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

nic dłużej. Jeśli używam private_key_bits 512 mogę wysłać

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

nic dłużej.

Na długich ciągów JavaScript konsola raporty: „Message zbyt długo RSA”

Następnie, jeśli chcesz zaszyfrować długich ciągów musi skompresować i podzielić je przed javascript szyfrowania i po odszyfrowaniu dołączyć i rozpakować na php, myślę zlib jest dobrym rozwiązaniem dla split/join, ponieważ jest obsługiwane przez javascript i php.

Mój kod roboczego jest następująca:

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

?> 

katalog drzewo koniecznością wygląda następująco:

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

i zapisywalnego katalogu PHP poza strefą publiczną o nazwie

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

Powiązane problemy