实现PHP和JavaScript的TripleDES加密解密(三)
介绍
这章节讲下在加密过程中遇到的一些坑。
内容
因为前端页面请求的时候会将一个32位16进制字符串转为 CryptoJs 类库里独有的数据结构 WordArray 去参与加密,因此需要在PHP里实现 WordArray 的相同数据结构
因为只用到了16进制转 WordArray,所以下面着重讲下该过程。
//解析16进制字符串
parse: function (hexStr) {
// Shortcut
var hexStrLength = hexStr.length;
// Convert
var words = [];
for (var i = 0; i < hexStrLength; i += 2) {
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
}
return new WordArray.init(words, hexStrLength / 2);
}
//wordarray类构造函数
init: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes != undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 4;
}
},
看上面代码会发现解析字符串的过程中会涉及到位运算(包括无符号右移、有符号左移),然后再测试过程中发现,JS的位运算和PHP的不一样,因此需要在PHP去实现和JS效果一致的位运算
//有符号左移
function ll($v, $n)
{
$t = ($v & 0xFFFFFFFF) << ($n & 0x1F);
return $t & 0x80000000 ? $t | 0xFFFFFFFF00000000 : $t & 0xFFFFFFFF;
}
//无符号右移
function uright($a, $n)
{
$c = 2147483647 >> ($n - 1);
return $c & ($a >> $n);
}
在实现上面位运算后就能成功在PHP去实现 WordArray 这个数据结构
//创建WordArray
function createWordArray($hexString)
{
$hexStrLength = strlen($hexString);
$words = [];
for ($i = 0; $i < $hexStrLength; $i += 2) {
$words[uright($i,3)] |= ll(hexdec(substr($hexString,$i, 2)),(24 - ($i % 8) * 4));
}
return [
'words'=>$words,
'sigBytes'=>$hexStrLength/2
];
}
上面则是将16进制字符串转为 WordArray 数据结构的过程
总结
感觉在实现PHP进行 TripleDES 的加密解密实现时,更能体会到语言只是工具,不变的是思想。只要思想懂了,不管在哪个语言里都能实现。