javascript - 使用Javascript库SJCL加密,使用PHP解密

标签 javascript php encryption cryptography

我正在使用这个库:https://github.com/bitwiseshiftleft/sjcl

我想在客户端加密一个字符串,通过URL传递它,然后在后端解密它。

这是 JS:

<script src="https://bitwiseshiftleft.github.io/sjcl/sjcl.js"></script>
<script>
var ciphertext = sjcl.encrypt("password", "Hello World!")
var plaintext = sjcl.decrypt("password", ciphertext)
console.log(ciphertext)
console.log(plaintext)
</script>

结果。

console.log(纯文本):

{"iv":"XA+HFebsM7WiVy0Ko8EEuA==","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"f4BX8a9fUPM=","ct":"a4LesnrsT7C6MmkxZifSw7FsDyI="}

console.log(密文):

Hello World!

如您所见,加密和解密按照 JS 的预期工作。当我尝试使用 PHP 解密它时,问题就出现了:

$password = 'password';
$input    = json_decode('{"iv":"XA+HFebsM7WiVy0Ko8EEuA==","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"f4BX8a9fUPM=","ct":"a4LesnrsT7C6MmkxZifSw7FsDyI="}', true);
$digest   = hash_pbkdf2('sha256', $password, base64_decode($input['salt']), $input['iter'], 16, true);
$cipher   = $input['cipher'] . '-' . $input['ks'] . '-' . $input['mode'];
$ct       = substr(base64_decode($input['ct']), 0, - $input['ts'] / 8);
$tag      = substr(base64_decode($input['ct']), - $input['ts'] / 8);
$iv       = base64_decode($input['iv']);
$adata    = $input['adata'];

$dt = openssl_decrypt($ct, $cipher, $digest, OPENSSL_RAW_DATA, $iv, $tag, $adata);
var_dump($dt);
while ($msg = openssl_error_string()) {
    echo $msg . "\n";
}

var_dump($dt) 的结果是 false,这是当 openssl_decrypt 无法解密字符串时发生的情况。 我肯定错过了一些东西,任何人都可以帮我注意到它是什么吗?

最佳答案

当使用模式“gcm”和 128 位 iv 时,我已经让它运行了。

  var key = 'password';
  var p = { mode: 'gcm', iv: sjcl.random.randomWords(4, 0) };
  var encrypted = sjcl.encrypt(key, 'Hello World', p);

这会导致输出,例如:

{"iv":"/Jyo0DNWt0CNUW6AYkpnBw==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"gcm","adata":"","cipher":"aes","salt":"jFSuZEEICq8=","ct":"7+M0Wv79zKXu4SUYJPZAIIBYgw=="}

此 JSON 输出用作 PHP 中的输入:

$input = json_decode('<JSON output from above goes here>', true);

可以像上面的示例代码中提到的那样传递给解密:

$password = 'password';
$digest   = hash_pbkdf2('sha256', $password, base64_decode($input['salt']), 
$input['iter'], 0, true);
$cipher   = $input['cipher'] . '-' . $input['ks'] . '-' . $input['mode'];
$ct       = substr(base64_decode($input['ct']), 0, - $input['ts'] / 8);
$tag      = substr(base64_decode($input['ct']), - $input['ts'] / 8);
$iv       = base64_decode($input['iv']);
$adata    = $input['adata'];

$dt = openssl_decrypt($ct, $cipher, $digest, OPENSSL_RAW_DATA, $iv, $tag, $adata);
var_dump($dt);

这对我使用 PHP 版本 7.1.9 有效

关于javascript - 使用Javascript库SJCL加密,使用PHP解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43698495/

相关文章:

em 中的 Javascript : getting the display width of text string in a pre container,

PHP MySQL 检查数组中的项目是否存在于表中,然后显示

php - iOS Swift 5 - 通过调用 PHP 函数使用服务器上传文件

c# - RSACryptoServiceProvider.Encrypt(byte[] rgb, bool fOAEP) 中的 rgb 是什么

Javascript 简写 if 语句

javascript - HTML 表格标题中的垂直(旋转)文本

ssl - 非RSA TLS1.2数据包解密

java - 如何以编程方式加密/解密 JSP 中的纯文本凭据?

javascript - 将网页文本中的匹配词更改为按钮

php - Laravel Auth 自定义字段