1

I am creating a public/private key on the server, sending the public key to the JavaScript client where it encrypts a users password using cryptico.js library: https://github.com/wwwtyro/cryptico/blob/master/cryptico.js

$res = openssl_pkey_new(array( 
  'private_key_bits' => 2048,
  'private_key_type' => OPENSSL_KEYTYPE_RSA,
  'digest_alg' => 'sha256'
));

Following some advices from this older post Encrypt with Cryptico.js, Decrypt with OpenSSL

//Made Public key compatible with cryptico.js

$detail = openssl_pkey_get_details($res);
$n = base64_encode($detail['rsa']['n']);
$e = bin2hex($detail['rsa']['e']);

$publicKey = "$n|$e";
openssl_pkey_export($res, $privateKey);

file_put_contents("public_key",$publicKey);
file_put_contents("private_key",$privateKey);

Made two modifications in cryptico.js as suggested in the same post

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
}

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 in client js:

var publicKey = '<php echo file_get_contents("public_key")?>';
var encrypted = cryptico.encrypt("plain text", publicKey);
var data = 'encrypted_post_var='+encrypted.chiper;

Then I send data via AJAX POST, and I can verify that it has been successfully received with $_POST["encrypted_post_var"]

in php:

$private = openssl_pkey_get_private(file_get_contents("private_key"));

//!!! THAT is the problem because here openssl_private_decrypt() return FALSE !!!
openssl_private_decrypt(base64_decode($_POST["encrypted_post_var"]), $decrypted, $privateKey); 
Community
  • 1
  • 1
MTK
  • 3,300
  • 2
  • 33
  • 49

1 Answers1

1

SOLVED

Finally I found one way to get it working :)

In my.encrypt() function i have changed this line:

cipherblock += my.b16to64(publickey.encrypt(plaintext));

to

cipherblock = publickey.encrypt(plaintext);
//that return the cipherblock (ciphertext) in hex format instead base64

And in php i have changed that:

openssl_private_decrypt(base64_decode($_POST["encrypted_post_var"]), $decrypted, $privateKey);

to:

openssl_private_decrypt(pack('H*',$_POST["encrypted_post_var"]), $decrypted, $privateKey);

Now working good !

MTK
  • 3,300
  • 2
  • 33
  • 49