php openssl发送给前端,js前端加密,php后端解密(crypto-js,openssl_decrypt)-Go语言中文社区...

本文记录了使用ReactNative前端和PHP后端进行AES加密数据传输时遇到的问题及解决方案。前端使用crypto-js库加密,后端通过openssl_decrypt解密。主要难点包括:秘钥长度匹配、POST数据格式导致的解密失败,以及解决方法——使用JSON格式传输数据和正确设置解密选项。
摘要由CSDN通过智能技术生成

最近在做react native项目,需要对用户登录数据进行加密传输,前端加密采用开源js库crypto-js,后端解密用php(我的是php7版本)自带的openssl_decrypt方法,踩了许多坑,记录一下。

一、安装/配置依赖库

1. crypto-js安装

npm install crypto-jsGitHub项目地址:https://github.com/brix/crypto-js

官方文档中有介绍具体使用的方法,很清晰。

2. php openssl 配置

参考文章:https://www.cnblogs.com/phpxuetang/p/5656266.html

openssl_encrypt的基本使用形式:openssl_decrypt(data, method, key, options, iv)

data:待解密的数据

method:可以选aes-128-cbc、aes-256-cbc等,官网上的method列表如下:

(

[0] => AES-128-CBC

[1] => AES-128-CFB

[2] => AES-128-CFB1

[3] => AES-128-CFB8

[5] => AES-128-OFB

[6] => AES-192-CBC

[7] => AES-192-CFB

[8] => AES-192-CFB1

[9] => AES-192-CFB8

[11] => AES-192-OFB

[12] => AES-256-CBC

[13] => AES-256-CFB

[14] => AES-256-CFB1

[15] => AES-256-CFB8

[17] => AES-256-OFB

[18] => BF-CBC

[19] => BF-CFB

[21] => BF-OFB

[22] => CAST5-CBC

[23] => CAST5-CFB

[25] => CAST5-OFB

[41] => IDEA-CBC

[42] => IDEA-CFB

[44] => IDEA-OFB

[53] => aes-128-cbc

[54] => aes-128-cfb

[55] => aes-128-cfb1

[56] => aes-128-cfb8

[58] => aes-128-ofb

[59] => aes-192-cbc

[60] => aes-192-cfb

[61] => aes-192-cfb1

[62] => aes-192-cfb8

[64] => aes-192-ofb

[65] => aes-256-cbc

[66] => aes-256-cfb

[67] => aes-256-cfb1

[68] => aes-256-cfb8

[70] => aes-256-ofb

[71] => bf-cbc

[72] => bf-cfb

[74] => bf-ofb

[75] => cast5-cbc

[76] => cast5-cfb

[78] => cast5-ofb

[94] => idea-cbc

[95] => idea-cfb

[97] => idea-ofb

)

options:有OPENSSL_RAW_DATA和OPENSSL_ZERO_PADDING两种,前者会默认采用PKCS#7进行补位,输出结果是加密后的原始结果,没有用base64编码;后者要求被加密的数据必须是“加密块”的整数倍,也就需要自己对加密数据进行补位处理。

iv:一个初始非零向量(必须是16位)

二、采坑记录

我采用的是aes加密的方式,

注意坑1:openssl_encrypt中aes-128-cbc、aes-256-cbc中的128、256是与秘钥位数有关的,16位秘钥需要使用aes-128-cbc模式。参考文章:https://www.douban.com/note/628737539/

注意坑2:加密后的字符串如果直接用post form形式提交给php后端,会出现无法解密的情况,经过多次测试,终于找到原因。

这是我form表单里提交的密文:

a2a685fc63c907ba53c536b418910f4c.png

php后端获取'data'数据后得到的密文:

11669e5364f01fa330c0d60afe70d701.png

详细看!字符'+'还有'/'解析方式不同,得到的是完全不同的密文!!

所以,我最后前端是用json格式传输的数据,php后端用file_get_contents("php://input");获取前端传送过来的json数据。php获取json数据可参考文章:http://blog.csdn.net/lee00047/article/details/73650433

三、代码实现//前端js,使用crypto-js对数据进行AES加密

function encrypt(text){

var key = CryptoJS.enc.Latin1.parse('1234567890654321'); //为了避免补位,直接用16位的秘钥

var iv = CryptoJS.enc.Latin1.parse('1234567890123456'); //16位初始向量

var encrypted = CryptoJS.AES.encrypt(text, key, {

iv: iv,

mode:CryptoJS.mode.CBC,

padding:CryptoJS.pad.ZeroPadding

});

return encrypted;

}

//后端php,类函数appLogin()

public function appLogin(){

$post = $this->request->post();

$encrypted = $post['data'];

$key = "1234567890654321";

$iv = "1234567890123456";

$decrypted = openssl_decrypt($encrypted, 'aes-128-cbc', $key, OPENSSL_ZERO_PADDING , $iv);

…… //其他处理,解密后的字符串是带有'u0000'补位的原始结果,需要自行去掉

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于您的问题,我可以为您提供以下答案: 在PHP 7.2及以上版本中,可以通过openssl扩展实现AES加密。具体实现方式如下: 1. AES加密 ```php function aesEncrypt($data, $key, $iv) { $encrypted = openssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); return base64_encode($encrypted); } ``` 其中,$data为待加密的数据,$key为加密密钥,$iv为初始化向量,函数返回值为加密后的数据(base64编码)。 2. AES解密 ```php function aesDecrypt($data, $key, $iv) { $encrypted = base64_decode($data); $decrypted = openssl_decrypt($encrypted, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); return $decrypted; } ``` 其中,$data为待解密的数据(base64编码),$key为解密密钥,$iv为初始化向量,函数返回值为解密后的数据。 通过以上函数实现的AES加密可以与JS进行互通,具体实现方式可以参考以下示例: 1. JS加密 ```javascript function aesEncrypt(data, key, iv) { var cipher = crypto.createCipheriv('aes-128-cbc', key, iv); var encrypted = cipher.update(data, 'utf8', 'base64'); encrypted += cipher.final('base64'); return encrypted; } ``` 其中,data为待加密的字符串,key为加密密钥,iv为初始化向量,函数返回值为加密后的数据(base64编码)。 2. JS解密 ```javascript function aesDecrypt(data, key, iv) { var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv); var decrypted = decipher.update(data, 'base64', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } ``` 其中,data为待解密的数据(base64编码),key为解密密钥,iv为初始化向量,函数返回值为解密后的数据。 注意事项: 1. 在PHP中,$key和$iv必须为16位长度的字符串,可以通过以下方式生成: ```php $key = openssl_random_pseudo_bytes(16); $iv = openssl_random_pseudo_bytes(16); ``` 2. 在JS中,key和iv必须为Buffer类型,可以通过以下方式生成: ```javascript var key = crypto.randomBytes(16); var iv = crypto.randomBytes(16); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值