dongpao1921 2017-04-29 17:22
浏览 246

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

I am using this library: https://github.com/bitwiseshiftleft/sjcl

I want to encrypt a string client side, pass it through the URL, and then decrypt it in the backend.

This is the 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>

Results.

console.log(plaintext):

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

console.log(ciphertext):

Hello World!

As you can see, encryption and decryption work as intended with JS. The problem comes when I try to decrypt it using 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 . "
";
}

Result of var_dump($dt) is false, which is what happens when the openssl_decrypt fails to decrypt the string. Surely I'm missing something, anyone could help me notice what it is?

  • 写回答

1条回答 默认 最新

  • dop82210 2018-10-31 10:42
    关注

    I've got it running when using mode 'gcm' with a 128-bit iv.

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

    This leads to output e.g.:

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

    This JSON output is used as input in PHP:

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

    which can be passed to decryption like mentioned in the example code above:

    $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);
    

    This worked for me using PHP version 7.1.9

    评论

报告相同问题?

悬赏问题

  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机