Encrypt with Cryptico.js, Decrypt with OpenSSL

前端 未结 1 1672
醉话见心
醉话见心 2021-01-03 14:36

I am creating a public/private key on the server, sending the key to the JavaScript client where it encrypts a users password. The client sends the password to the server,

1条回答
  •  时光说笑
    2021-01-03 15:19

    cryptico.js could work with openssl, but we have to modify it a bit.

    it don't directly recognize the public key in pem format (which openssl use). we have to extract the 'n' and 'e' part of a public key in php side:

    $key = openssl_pkey_new(array( 
      'private_key_bits' => 1024,
      'private_key_type' => OPENSSL_KEYTYPE_RSA,
      'digest_alg' => 'sha256'
    ));
    
    $detail = openssl_pkey_get_details($key);
    $n = base64_encode($detail['rsa']['n']);
    $e = bin2hex($detail['rsa']['e']);
    

    also, cryptico.js hardcoded the 'e' part of a public key (see definition of publicKeyFromString in api.js), so we need to fix this:

    my.publicKeyFromString = function(string)
    {
      var tokens = string.split("|");
      var N = my.b64to16(tokens[0]);
      var E = tokens.length > 1 ? tokens[1] : "03";
      var rsa = new RSAKey();
      rsa.setPublic(N, E);
      return rsa
    }
    

    now we are able to encrypt strings:

    var publicKey = "{$n}|{$e}",
        encrypted = cryptico.encrypt("plain text", publicKey);
    

    job is not finished yet. the result of cryptico.encrypt is NOT simply encrypted by RSA. indeed, it was combined of two parts: an aes key encrypted by RSA, and the cipher of the plain text encrypted with that aes key by AES. if we only need RSA, we could modify my.encrypt:

    my.encrypt = function(plaintext, publickeystring, signingkey)
    {
      var cipherblock = "";
      try
      {
        var publickey = my.publicKeyFromString(publickeystring);
        cipherblock += my.b16to64(publickey.encrypt(plaintext));
      }
      catch(err)
      {
        return {status: "Invalid public key"};
      } 
      return {status: "success", cipher: cipherblock};
    }
    

    now we are able to decrypt the cipher with openssl:

    $private = openssl_pkey_get_private("YOUR PRIVATE KEY STRING IN PEM");
    // $encrypted is the result of cryptico.encrypt() in javascript side
    openssl_private_decrypt(base64_decode($encrypted), $decrypted, $private);
    // now $decrypted holds the decrypted plain text
    

    0 讨论(0)
提交回复
热议问题