2009-03-04 75 views
7

Tôi muốn mã hóa bằng Javascript và sau đó giải mã bằng PHP. Có các triển khai RSA cho Javascript và PHP nhưng chúng không tương thích. Tôi không thể giải mã trong PHP chính xác những gì tôi đã mã hóa với Javascript.Mã hóa/giải mã RSA tương thích với Javascript và PHP

Có ai biết thư viện/mã sẽ hoạt động cả với Javascript và PHP không?

Cảm ơn.

+1

Có vẻ như bạn đang cân nhắc điều này để mã hóa dữ liệu nhạy cảm giữa máy khách và máy chủ. Bạn được cảnh báo rằng điều này sẽ KHÔNG cung cấp bất kỳ sự bảo mật nào đối với một cuộc tấn công ở giữa mà bất kỳ dữ liệu nào đi qua đều sẽ bị xâm phạm. Sử dụng HTTPS để mã hóa đầu cuối an toàn, được xác thực. – deed02392

Trả lời

1

Nếu bạn thiết lập máy chủ của mình để sử dụng SSL thì bạn có thể truyền mã hóa qua ajax bằng https. Đó có lẽ là cách tốt nhất để mã hóa dữ liệu giữa javascript và php. Nếu bạn muốn làm cho nó cho mình có một cơ hội lớn, bạn sẽ vít lên một nơi nào đó và hệ thống sẽ không được an toàn.

Google về cách thiết lập https cho máy chủ của bạn.

0

Tôi cho rằng bạn có lý do hợp lệ để làm điều đó ngoài việc tự mình làm https, vì vậy tôi muốn nói rằng nếu bạn tuân thủ các tiêu chuẩn, bạn sẽ có thể dễ dàng giải mã bằng bất kỳ công nghệ nào hỗ trợ các tiêu chuẩn này. làm việc

Ví dụ: nếu bạn mã hóa dữ liệu của mình ở định dạng PKCS # 7, hãy chắc chắn rằng thư viện php của bạn biết rằng dữ liệu đầu vào là PKCS # 7.

Cũng đảm bảo rằng khóa mã hóa của bạn không bị tranh giành giữa máy chủ và ứng dụng khách. Bạn đã cố giải mã dữ liệu của mình bằng thư viện javascript chưa?

Hy vọng điều này có thể giúp ...

0

Có thể bạn có thể trợ giúp bằng cách đặt mã bạn đang sử dụng cho cả js và php.

Ngoài ra, có thể bạn có thể cụ thể hơn về lý do bạn cần sử dụng js và php. Có lẽ bạn chỉ có thể sử dụng php và AJAX (để truy vấn cùng một chức năng php) khi bạn đang sử dụng js.

+0

Tôi nghĩ rằng OP đang cố gắng gửi một cái gì đó giống như mật khẩu cho máy chủ dưới dạng mã hóa. Nếu bạn gửi mật khẩu cho một hàm php bằng AJAX, thì bạn vẫn sẽ gửi mật khẩu thuần văn bản tới cuộc gọi AJAX và sau đó mã hóa nó trong phương thức php sẽ không còn ý nghĩa nữa – lugte098

7

Dưới đây là một hoạt Javascript RSA thư viện mã hóa: http://www.ohdave.com/rsa/

Và tôi nghĩ bạn có thể sử dụng giống như lớp này để giải mã mã hóa chuỗi tạo - http://www.phpclasses.org/browse/package/4121.html

Hãy cho tôi biết nếu bạn quản lý được công việc này với nhau, như tôi đang nhìn vào chủ đề này (tôi thực sự tìm thấy bài đăng này tìm kiếm câu trả lời này cho bản thân mình: P).

Edit: Hãy nhìn xem, tôi cũng đã tìm thấy này - http://www.sematopia.com/?p=275 - dường như có liên quan đến trước hai cũng ...

0

Tôi không phải là một để thổi còi còi của riêng tôi nhưng tôi có một dự án tại github.com sẽ thực hiện chức năng này.

Khoá cá nhân được tạo trên máy chủ, khóa công cộng và chứng chỉ pkcs # 7 cũng được lấy từ khóa riêng tư. Khóa công khai được gửi tới máy khách vào thời điểm mà mỗi phần tử biểu mẫu được gán với biểu mẫu được chỉ định được mã hóa trước khi được gửi đến máy chủ.

Nó tương thích 100% OpenSSL vì nó sử dụng phần mở rộng PHP OpenSSL để tạo, mã hóa và giải mã dữ liệu.

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

Dự án này không phải là an toàn như PGP vì JavaScript sẽ không ký tên và mã hóa email cho đến khi dữ liệu mẫu được gửi đến máy chủ, nhưng các dữ liệu hình thức mà phải được mã hóa và hoặc ký được mã hóa sử dụng mã hóa khóa công khai RSA trước khi được gửi đến máy chủ.

Một lần nữa dự án không hoàn chỉnh về xác thực và ký email nhưng đối với mã hóa biểu mẫu thông thường sử dụng khóa công khai, nó hoạt động rất tốt.

5

Hãy thử ví dụ đơn giản sau đây.

Nó được sử dụng một mã nguồn mở thư viện 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); 
} 
?> 

Thưởng thức!

+1

Dành cho độc giả tương lai: David.Ask được đề xuất trong bản chỉnh sửa bị từ chối cho câu trả lời này, điều này cũng nên được thêm vào đầu: '' – Tieme

+0

Sử dụng tính năng này với PHP anwser làm việc như một sự quyến rũ cho tôi https://github.com/travist/jsencrypt/ –

0

Tôi tìm thấy thư viện jsencrypt này (http://travistidwell.com/jsencrypt), sau 2 ngày thử tôi nhận giải pháp của mình.

Vấn đề duy nhất tôi nhận được là khi tôi gửi văn bản dài. Đó là bởi vì RSA, theo định nghĩa, hỗ trợ các chuỗi có chiều dài hạn chế.

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

RSA, theo định nghĩa của PKCS # 1, mã hóa "thông điệp" của kích thước giới hạn. Với "đệm đệm v1.5" thường được sử dụng và khóa RSA 2048 bit, kích thước tối đa dữ liệu có thể được mã hóa bằng RSA là 245 byte. Không còn nữa.

ví dụ: Nếu tôi sử dụng private_key_bits 1024 tôi có thể gửi

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

gì nữa. Nếu tôi sử dụng private_key_bits trong số 512 tôi có thể gửi

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

không còn nữa.

Mở chuỗi dài JavaScript console báo cáo: "Thông điệp quá dài cho RSA"

Sau đó, nếu bạn muốn mã hóa chuỗi dài bạn phải nén và chia chúng trước khi mã hóa javascript và sau khi giải mã tham gia và giải nén trên php, tôi nghĩ zlib là một giải pháp tốt cho việc chia/nối vì nó được hỗ trợ trên javascript và php.

mã làm việc của tôi là như sau:

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

?> 

mục cây phải trông giống như:

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

và ghi thư mục bằng php bên ngoài của khu vực công cộng được đặt tên

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

Các vấn đề liên quan