php - 关于可逆加密的问题
阿神
阿神 2017-04-11 09:11:28
[PHP讨论组]

经常看到一些加密解密的方法用到的都是位运算,左移,右移,亦或(这个我知道为什么可逆),与,之类的。
不太明白为什么要这么做能达到加密解密。
希望大神给指点一下。
不要说什么去看位运算转成2进制以后是怎么运算的,这些我都知道,我就是想了解为什么通常都是转成2进制去做位运算来达到这样的效果

阿神
阿神

闭关修行中......

全部回复(4)
伊谢尔伦

先贴两段 可加密解密 [逆向]的方法 ,对此同样有兴趣,一起学习


$str = enCrypt('I love segmentfault.com');

var_dump($str); 
// 44=3BX=4cxEKSWm4Cb37xwtmwtHgxG9GF

var_dump(deCrypt('VChm-=IMqluO6F5F+ZWueQeDn2pSSolPS')); 
// I love segmentfault.com

加密

    /**
     * 可逆的字符串加密函数[无依赖简版]
     * @param int $txtStream 待加密的字符串内容
     * @param int $password 加密密码
     * @return string 加密后的字符串
     */
     function enCrypt($txtStream,$password = 'ENCRYPT_KEY'){
        //密锁串,不能出现重复字符,内有A-Z,a-z,0-9,/,=,+,_,
        $lockstream = 'st=lDEFABCNOPyzghi_jQRST-UwxkVWXYZabcdef+IJK6/7nopqr89LMmGH012345uv';
        //随机找一个数字,并从密锁串中找到一个密锁值
        $lockLen = strlen($lockstream);
        $lockCount = rand(0,$lockLen-1);
        $randomLock = $lockstream[$lockCount];
        //结合随机密锁值生成MD5后的密码
        $password = md5($password.$randomLock);
        //开始对字符串加密
        $txtStream = base64_encode($txtStream);
        $tmpStream = '';
        $i=0;$j=0;$k = 0;
        for ($i=0; $i<strlen($txtStream); $i++) {
        $k = ($k == strlen($password)) ? 0 : $k;
        $j = (strpos($lockstream,$txtStream[$i])+$lockCount+ord($password[$k]))%($lockLen);
        $tmpStream .= $lockstream[$j];
        $k++;
        }
        return $tmpStream.$randomLock;

    }

解密


    /**
     * 可逆的字符串解密函数[无依赖简版]
     * @param int $txtStream 待加密的字符串内容
     * @param int $password 解密密码
     * @return string 解密后的字符串
     */
     function deCrypt($txtStream,$password = 'ENCRYPT_KEY'){
        //密锁串,不能出现重复字符,内有A-Z,a-z,0-9,/,=,+,_,
        $lockstream = 'st=lDEFABCNOPyzghi_jQRST-UwxkVWXYZabcdef+IJK6/7nopqr89LMmGH012345uv';

        $lockLen = strlen($lockstream);
        //获得字符串长度
        $txtLen = strlen($txtStream);
        //截取随机密锁值
        $randomLock = $txtStream[$txtLen - 1];
        //获得随机密码值的位置
        $lockCount = strpos($lockstream,$randomLock);
        //结合随机密锁值生成MD5后的密码
        $password = md5($password.$randomLock);
        //开始对字符串解密
        $txtStream = substr($txtStream,0,$txtLen-1);
        $tmpStream = '';
        $i=0;$j=0;$k = 0;
        for($i=0; $i<strlen($txtStream); $i++){
        $k = ($k == strlen($password)) ? 0 : $k;
        $j = strpos($lockstream,$txtStream[$i]) - $lockCount - ord($password[$k]);
        while($j < 0){
        $j = $j + ($lockLen);
        }
        $tmpStream .= $lockstream[$j];
        $k++;
        }
        return base64_decode($tmpStream);
    }
PHPz

不管采用何种算法,都是想自定义加密算法,因为是自定义的所以常见的破解方式都是不可行的,必须有针对的开发破解方法。其他方式也可以达到加密,位运算常用的一种而已。

你是位运算也好,字符串替换也好都可以起到加密的效果。

首先加密就是将原有的数据处理,变得和原来不同,通过一定的算法可逆或者不可逆。比如密码,一般采用不可逆算法。比如消息传递,采用的就是可逆的。

字符串替换也可以看成一种加密方式,比如,有个字典,标明A=>C,B=》e等一些字母或者汉字或者符号的对应表,就和摩斯电码差不多,这样替换之后就进行了加密,必须有字典,才可以进行逆运算。

位运算也可以理解成字符串替换,因为移位也造成了字符串更改,所以归根结底都是字符串的替换。

结论,不管啥方法都是将原内容和最终内容做到显示上的不同而已。所以不必纠结为什么用位运算等

大家讲道理

其实这玩应很简单,加密就是为了让别人看不出来你的数据到底是啥。举个简单的例子,你有一个关键数据1234,你不希望别人看见。但是数据传输过程中有可能被劫持,数据就泄漏了。所以你在数据传输之前把这个数据按照一定的算法进行加密。比如算法是每位数字加1,结果就是2345了。这样即使被劫持了,得到数据但得不到解密算法,也不能够得到正确的数据。这里的算法就是你提到的位移什么的。
当把数据转换成二进制后,按照算法进行位移,数据就会有上边提到的变化,1234->2345。当然也可能是变成了别的,无所谓是什么,只要不是原来的数据就可以了。正如楼上所说的,你不必纠结于为什么加密算法要用位移或者异或这种不好理解的东西,其实你自己随便写个规则效果是一样的,只是把数据按照一定规则改变了,等需要的时候再用反规则把数据翻译出来。

天蓬老师

(发送方)明文<=>密文<=>明文(接收方),加密一个原因是对信道的不信任。为了防止他人窃听破解,我们需要在发送方对明文进行加密,相似地,在接收方利用相应手段对密文进行解密。

DES是常见的对称加密方法,它就是很经典的通过多轮位运算产生密文,并且在接收方解密是可逆的。首先,DES是可逆的,因此可以双方共享一个密钥进行明文的加密传输。其次,当信道被人窃听,需要保证破解密文的复杂度极高(代价太大就没有必要破解,一切利益驱动),以至于密文近似不可被破解。

我对DES的理解还仅限于书本、考试、开源代码,其实本身不是很理解DES破解复杂度如何证明。现在加密方式已经升级到AES-256了,就说明安全这块一直都有破解高手与加密高手互相斗法。如果想理解破解的复杂度,建议还是阅读论文,这些都是有数学在背后支持的。Attack on DES 是google搜来的一份综述PPT,可以一览。

如果本身不是做安全的,加密解密最好还是直接用开源库,因为不定自己写的会出什么bug。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号