AES 256在客户端(JS)和在服务器(PHP) [英] AES 256 on the client side (JS) and in the server (PHP)

查看:237
本文介绍了AES 256在客户端(JS)和在服务器(PHP)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用相同类型的操作(即AES-256)在服务器端和客户端上加密和解密数据。

I'm trying to encrypt and decrypt data on the server side and the client using the same type of operation, which is AES-256.

在服务器我使用PHP和客户端我使用CryptoJS到目前为止我只能加密和解密服务器上的客户端,请参阅代码:

On the server I use PHP and client I use CryptoJS so far I could only encrypt and decrypt the client on the server, see the code:

JS / p>

JS

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/pbkdf2.js"></script>
<script>
    var salt = CryptoJS.lib.WordArray.random(128/8); 
    var key256Bits500Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 256/32, iterations: 500 });
    var iv  = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');

    var encrypted = CryptoJS.AES.encrypt("Message", key256Bits500Iterations, { iv: iv });  
    var data_base64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64); 
    var iv_base64   = encrypted.iv.toString(CryptoJS.enc.Base64);       
    var key_base64  = encrypted.key.toString(CryptoJS.enc.Base64);
</script>

PHP

<?php
    $encrypted = base64_decode("data_base64"); // data_base64 from JS
    $iv        = base64_decode("iv_base64");   // iv_base64 from JS
    $key       = base64_decode("key_base64");  // key_base64 from JS

    $plaintext = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_CBC, $iv ), "\t\0 " );

如何对数据进行双方加密和解密(客户端和服务器)使用PHP和CryptoJS的语言?

How can I encrypt and decrypt data on both sides (client and server) so that communicate in the same language using PHP and CryptoJS?

推荐答案

CryptoJS默认使用PKCS#5 / PKCS#7填充,而MCrypt只支持ZeroPadding。

Your code looks fine apart from a padding mismatch. CryptoJS uses PKCS#5/PKCS#7 padding by default whereas MCrypt only supports ZeroPadding.

如果你只是发送文本明文,那么你可以安全地使用

If you're only sending textual plaintexts, then you can safely use

CryptoJS.AES.encrypt("Message", key, { iv: iv, padding: CryptoJS.pad.ZeroPadding });

如果没有,则应使用 PHP中的正确pkcs7unpad

$plaintext = pkcs7unpad( mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_CBC, $iv ), 16 );

您的代码的其他问题是您直接使用 CryptoJS.AES.encrypt (...)。toString()。这将创建一个OpenSSL格式的字符串,这不是纯粹的密文。您需要使用

Other problems with your code are that you directly use CryptoJS.AES.encrypt(...).toString(). This will create an OpenSSL formatted string which is not purely the ciphertext. You need to use

CryptoJS.AES.encrypt(...).ciphertext.toString(CryptoJS.enc.Base64);

也可以确定编码。

现在,这只是模糊处理,因为你和密文一起发送密钥。我怀疑你想在PHP中导出密钥。如果是,则只需要在服务器知道密码的情况下发送随机盐和密文。

Right now, this is only obfuscation, since you're sending the key along with the ciphertext. I suspect that you want to derive the key in PHP too. If yes, then you will only need to send the random salt along with the ciphertext under the assumption that the server knows the password.

PHP提供了一个版本5.5起的PBKDF2实施

不包含PBKDF2的完整JavaScript部分:

Full JavaScript part without PBKDF2 involvement:

var message = 'My string - Could also be an JS array/object';
var iv = 'a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8';
var key = 'c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8'; // 256-bit hex encoded

var keyBytes = CryptoJS.enc.Hex.parse(key);
var ivBytes = CryptoJS.enc.Hex.parse(iv);

var encrypt = CryptoJS.AES.encrypt(message, keyBytes, {
    iv: ivBytes, 
    padding: CryptoJS.pad.ZeroPadding 
}).ciphertext.toString(CryptoJS.enc.Base64);

产生:


j86KHBVRsDGKUnOiYdkEotsFL / lY / 1tzz / h3Ay + vlEX11fC055m7vaF6q7w13eUj

j86KHBVRsDGKUnOiYdkEotsFL/lY/1tzz/h3Ay+vlEX11fC055m7vaF6q7w13eUj

没有PBKDF2参与的完整PHP部分:

Full PHP part without PBKDF2 involvement:

<?php

$iv = 'a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8';
$key = 'c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8';
$ct = 'j86KHBVRsDGKUnOiYdkEotsFL/lY/1tzz/h3Ay+vlEX11fC055m7vaF6q7w13eUj';

$ivBytes = hex2bin($iv);
$keyBytes = hex2bin($key);
$ctBytes = base64_decode($ct);

$decrypt = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $keyBytes, $ctBytes, MCRYPT_MODE_CBC, $ivBytes));

echo $decrypt;

产生:


我的字符串 - 也可以是一个JS数组/对象

My string - Could also be an JS array/object

这篇关于AES 256在客户端(JS)和在服务器(PHP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆