openssl_private_decrypt() 密文来自 cryptico.js return false
openssl_private_decrypt() with ciphertext from cryptico.js return false
我正在服务器上创建一个 public/private 密钥,将 public 密钥发送到 JavaScript 客户端,客户端使用 cryptico.js 库加密用户密码:
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'
));
听从这位老 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);
按照 post
中的建议对 cryptico.js 进行了两次修改
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};
}
现在在客户端 js 中:
var publicKey = '<php echo file_get_contents("public_key")?>';
var encrypted = cryptico.encrypt("plain text", publicKey);
var data = 'encrypted_post_var='+encrypted.chiper;
然后我通过AJAXPOST发送数据,我可以通过$_POST[验证是否已成功接收"encrypted_post_var"]
在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);
已解决
最后我找到了一种让它工作的方法:)
在 my.encrypt() 函数中我更改了这一行:
cipherblock += my.b16to64(publickey.encrypt(plaintext));
到
cipherblock = publickey.encrypt(plaintext);
//that return the cipherblock (ciphertext) in hex format instead base64
并且在 php 中我已经更改了:
openssl_private_decrypt(base64_decode($_POST["encrypted_post_var"]), $decrypted, $privateKey);
至:
openssl_private_decrypt(pack('H*',$_POST["encrypted_post_var"]), $decrypted, $privateKey);
现在工作正常!
我正在服务器上创建一个 public/private 密钥,将 public 密钥发送到 JavaScript 客户端,客户端使用 cryptico.js 库加密用户密码: 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'
));
听从这位老 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);
按照 post
中的建议对 cryptico.js 进行了两次修改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};
}
现在在客户端 js 中:
var publicKey = '<php echo file_get_contents("public_key")?>';
var encrypted = cryptico.encrypt("plain text", publicKey);
var data = 'encrypted_post_var='+encrypted.chiper;
然后我通过AJAXPOST发送数据,我可以通过$_POST[验证是否已成功接收"encrypted_post_var"]
在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);
已解决
最后我找到了一种让它工作的方法:)
在 my.encrypt() 函数中我更改了这一行:
cipherblock += my.b16to64(publickey.encrypt(plaintext));
到
cipherblock = publickey.encrypt(plaintext);
//that return the cipherblock (ciphertext) in hex format instead base64
并且在 php 中我已经更改了:
openssl_private_decrypt(base64_decode($_POST["encrypted_post_var"]), $decrypted, $privateKey);
至:
openssl_private_decrypt(pack('H*',$_POST["encrypted_post_var"]), $decrypted, $privateKey);
现在工作正常!