ci里怎么使用3des加密?
原来是使用下面这个类做的3des
加密,但是升级PHP7.1
后,mcrypt
整个移除了,现在用的是ci框架
,它应该是支持3des
加密的,但是加密出来的字符串跟以前的不一样,请问ci
里应该怎么加密?或者PHP7.1
怎么做到3des
加密?因为现在需要对接一个外部系统,他们要求用3des
加密...
<?php
class Des3 {
public static function encrypt($str, $key) {
$td = self::gettd($key);
$ret = strtoupper(bin2hex(mcrypt_generic($td, self::pkcs5_pad($str, 8))));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $ret;
}
public static function decrypt($str, $key) {
$td = self::gettd($key);
$ret = self::pkcs5_unpad(mdecrypt_generic($td, self::hex2bin(strtolower($str))));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $ret;
}
public static function hex2bin($hexData) {
$binData = "";
for($i = 0; $i < strlen ( $hexData ); $i += 2) {
$binData .= chr ( hexdec ( substr ( $hexData, $i, 2 ) ) );
}
return $binData;
}
private static function pkcs5_pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
private static function pkcs5_unpad($text) {
$pad = ord($text{strlen($text) - 1});
if ($pad > strlen($text)) {
return false;
}
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
return false;
}
return substr($text, 0, -1 * $pad);
}
private static function getiv() {
return pack('H16', '0102030405060708');
}
private static function gettd($key) {
$iv = self::getiv();
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
@mcrypt_generic_init($td, $key, $iv);
return $td;
}
}
现在使用1楼码友的推荐,用了 openssl_encrypt ,但是这个不知道怎样才能设置成是 3des 加密,我是这样的:
$sign = openssl_encrypt (
'abc9966',
'des-ede3-cbc' ,//感觉是这个函数没用对,但该用哪个呢?
'ABCLYHG22r5juqqlFRVfYdse',
0 ,//OPENSSL_RAW_DATA OPENSSL_ZERO_PADDING
'' //也有可能是 iv 没设置,该怎样设置呢?
);
加密出来的串也不对
ci我是这样加密的,当然,加密出来的串也是不对的:
$sign2 = $this->encryption->encrypt(
'abc9966',
array(
'driver' => 'openssl',
'cipher' => 'tripledes',
'mode' => 'cbc',
'hmac'=>false,
'raw_data'=>true,
'key' => 'ABCLYHG22r5juqqlFRVfYdse',
)
);
请问ci
里应该怎么加密?或者PHP7.1
怎么做到3des
加密?
ci里, tripledes
支持的密钥长度是 56
、112
、168
,但是我的密钥是24
,这个有问题吗?但是接口那边给的密钥就是这个长度,PHP用旧的那个类加密出来他们是可以解密的,ci自带类就不行...
找到一篇文章:http://blog.csdn.net/aloneswo...,里面提到“3des-ecb
加密方式;24位密钥,不足24位的右补0x00;”。这与ci
的说法不一致,而且ci里提到的3des
并不支持ecb
模式
最终能加密了!!!感谢一楼码友的提醒!!!
加密方法我写在此问题的答案中,为了感谢1楼,所以没有采纳我自己的答案
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
以前用这个库加密,现在用ci的话也可以用这个库加密,将它放到ci项目的
libraries
目录下(一般为application\libraries
),命名为Des3.php
。然后在控制器中载入这个类,
$this->load->library('Des3')
(Des3
首字母大小写无所谓,但是对应文件和类名要一致且除了首字母之外的大写会被强制转换成小写,所以不建议在中间使用大写字母);载入之后,在控制器中,使用
$this->des3->encrypt()
就可以使用Des3
类里面的encrypt
方法了,其他类似。Update
鉴于7.1废弃了mcrypt库,建议使用
openssl_encrypt
和openssl_decrypt
进行加密解密。参见:
https://stackoverflow.com/que...
http://php.net/manual/en/func...
终于找到答案了。先贴最终代码,用法跟
Des3类
一样:说说找到这个方法的过程吧...实在是找到了很多互相矛盾的资料,
比如以下
3des
到底支不支持ECB 模式
,这个导致一楼的码友都疑惑,为什么我用openssl
时,不选DES-ECB
模式?Des3类
里有用到iv
,为什么我不用?ci
的加密类里列出的表中,3des密钥
并不支持24位,为什么给接口我的人给的密钥是24位数的?其实以上的矛盾,我现在还没有答案,毕竟不是专门学密码学的人,我也不知道该不该深入。
最终的解决方案来自于这个问题的答案,这个答案中有人贴出了这代码
这
例子
列了mcrypt
和openssl
做3des加密
区别,我也注意到它的密钥,是24位。然而我直接把明文
、密钥
、iv
换成我的,发现这例子输出的两个密文是一样的,但是它们跟Des3类
的却是不一样。思考了一下,如果我一步一步把
例子的mcrypt版
改成跟Des3类
的一致,把相同的修改应用到例子的openssl版
,到最终是不是可以让这3个加密方法改成一致的?就按照这个思路走了!于是第一个问题出现了,
例子的mcrypt版
是用MCRYPT_MODE_CBC
,Des3类
是用MCRYPT_MODE_ECB
,这个倒是好改,但是openssl
的3des
并不支持ECB
啊!改了例子的mcrypt版
,那例子的openssl版
呢?这个实在没想到方法,一个个试吧,试到例子的mcrypt版
和例子的openssl版
的密文一致为止。先试openssl
的DES-EDE3
,结果一试就对了:以上两个输出的密文是一致的!
好了,本以为
例子的mcrypt版
和Des3类
的差别仅仅是加密模式,然而我改成MCRYPT_MODE_ECB
后,例子的mcrypt版
密文跟Des3类
的还是不一样,密文前半段是一样的,到后面就不一样了。类似这样的感觉:思考了一下,看了一下
Des3类
的实现,发现Des3类
有mcrypt_generic($td, self::pkcs5_pad($str, 8))
,Des3类
还给明文先打包了一下,行,我也加上打包函数最终,例子被我改成了上面这样。至此输出的两个密文,都跟
Des3类
的一致了,别提有多高兴了~~于是封装了起来openssl的key也不一定都得24位,只要使用你的pkcs5_pad方法进行补0即可,需要是8的倍数
基于楼主的总结 自己尝试的写出来使用
open_ssl
的解密方法,希望能帮助一下有需要的人们吧