真正兼容.net的php 3DES加解密

2009年06月15日  |  4:16 下午分类:Develop  |  标签:  |  

php中3des加密的结果与.Net/java不同的帖子与话题实在是太多了,

我前不久也在倒腾这些,不过今天已经搞定了,完全与.net中的兼容

<?php
class Crypt3Des
{
private $key = "";
private $iv = "";
/**
* 构造,传递二个已经进行base64_encode的KEY与IV
*
* @param string $key
* @param string $iv
*/
function __construct ($key, $iv)
{
if (empty($key) || empty($iv)) {
echo 'key and iv is not valid';
exit();
}
$this->key = $key;
$this->iv = $iv;
}
/**
*加密
* @param <type> $value
* @return <type>
*/
public function encrypt ($value)
{
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
$iv = base64_decode($this->iv);
$value = $this->PaddingPKCS7($value);
$key = base64_decode($this->key);
mcrypt_generic_init($td, $key, $iv);
$ret = base64_encode(mcrypt_generic($td, $value));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $ret;
}
/**
*解密
* @param <type> $value
* @return <type>
*/
public function decrypt ($value)
{
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
$iv = base64_decode($this->iv);
$key = base64_decode($this->key);
mcrypt_generic_init($td, $key, $iv);
$ret = trim(mdecrypt_generic($td, base64_decode($value)));
$ret = $this->UnPaddingPKCS7($ret);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $ret;
}
private function PaddingPKCS7 ($data)
{
$block_size = mcrypt_get_block_size('tripledes', 'cbc');
$padding_char = $block_size - (strlen($data) % $block_size);
$data .= str_repeat(chr($padding_char), $padding_char);
return $data;
}
private function UnPaddingPKCS7 ($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);
}
}
?>
直接拿去用吧。
转载时务必以超链接形式标明文章原始出处和作者信息。

10 位领导已批示 关于 “真正兼容.net的php 3DES加解密”

  1. zwws 发表于: 六月 15th, 2009 8:03 下午

    SyntaxHighlighter把下划线都strip掉了。

  2. 幻想曲 发表于: 六月 15th, 2009 9:21 下午

    啥下划线? :o

  3. keke 发表于: 七月 10th, 2009 10:31 上午

    给1楼解释一下……语法高亮把一些方法的下划线弄掉了
    传给Crypt3De的key/iv是先base64_encode过的?
    另外,key/iv分别有什么特殊要求吗?长度?字符类型或范围?

  4. 幻想曲 发表于: 七月 10th, 2009 1:59 下午

    哦,是这样的。
    如果你的加、解密不需要与.net结合的话,key/iv没有特定的要求。
    如:
    $k = base64_encode(‘abccefg’);
    $v = base64_encode(‘12345678′);
    echo ‘$k=’.$k.’
    ‘;
    echo ‘$v=’.$v.’
    ‘;

    $des = new Crypt3Des($k,$v);
    $ptname = $des->encrypt(‘yibin001′);

    echo ‘$ptname=’.$ptname;

    echo ‘
    解密:’.$des->decrypt($ptname);
    exit;

    输出为:
    $k=YWJjY2VmZw==
    $v=MTIzNDU2Nzg5MGFz
    $ptname=LZy+S50A8Nza69Y+y4rfEA==
    解密:yibin001

  5. 幻想曲 发表于: 七月 10th, 2009 2:02 下午

    如果要与.net互通的话,最好是.net方提供好密钥与向量。
    C#里关于des的GenerateKey()方法我还没有找到在php中的实现。

  6. 企鹅 发表于: 七月 23rd, 2009 11:58 上午

    我也是在烦这个问题.想问一下,能不能发一份 C# 端的对应加解密给我? 谢谢.

  7. 企鹅 发表于: 七月 24th, 2009 8:58 上午

    企鹅 :我也是在烦这个问题.想问一下,能不能发一份 C# 端的对应加解密给我? 谢谢.

    谢谢 幻想曲的 邮件.

  8. afu 发表于: 七月 24th, 2009 3:14 下午

    幻想曲您好
    我使用您提供的key/iv
    abccefg
    1234567890as
    在我的PHP環境上會得到錯誤

    Warning: mcrypt_generic_init() [function.mcrypt-generic-init]: Iv size incorrect; supplied length: 12, needed: 8 in /tripleDES/test.php on line 48

    請問要如何解決呢?
    謝謝

  9. 幻想曲 发表于: 七月 28th, 2009 1:59 下午

    这个是提示IV的长度不对,但我这边运行一切正常啊~~~~

  10. 幻想曲 发表于: 七月 28th, 2009 4:28 下午

    IV长度为8位


发表您的评论

1410168172122013183195114157619