Discuz!的authcode()函数是一个经典的流密码算法实现,discuz和ucenter的很多产品都使用此函数进行加解密。我从网上找了一份算法分析,并自己补充了一些注释,如下(觉得枯燥的朋友也可以跳过此部分,不影响阅读): ====================================================================== // string:明文或密文//operation:DECODE表示解密,其它表示加密 // key:密匙//expiry:密文有效期 //字符串解密加密 function authcode(string,operation = 'DECODE', key=′′,expiry = 0) { // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙 (初始化向量IV) ckeylength=4;//随机密钥长度取值0−32;//加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。(实际上就是iv)//取值越大,密文变动规律越大,密文变化=16的ckey_length 次方 // 当此值为 0 时,则不产生随机密钥 // 密匙 key=md5(key ? key:UCKEY);//密匙a会参与加解密keya = md5(substr(key,0,16));//密匙b会用来做数据完整性验证keyb = md5(substr(key,16,16));//密匙c用于变化生成的密文(初始化向量IV)keyc = ckeylength?(operation == 'DECODE' ? substr(string,0,ckey_length): substr(md5(microtime()), -ckeylength)):′′;//参与运算的密匙cryptkey = keya.md5(keya.keyc);key_length = strlen(cryptkey);//明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存keyb(密匙b),解密时会通过这个密匙验证数据完整性 // 如果是解码的话,会从第ckeylength位开始,因为密文前ckey_length位保存 动态密匙,以保证解密正确 string=operation == 'DECODE' ? base64_decode(substr(string,ckey_length)) : sprintf('%010d', expiry?expiry + time() : 0).substr(md5(string.keyb), 0, 16).string;string_length = strlen(string);result = ''; box=range(0,255);rndkey = array(); // 产生密匙簿 for(i=0;i <= 255; i++) { rndkey[i]=ord(cryptkey[ikey_length]); } // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度 for(j=i = 0; i<256;i++) { j=(j + box[i] + rndkey[i]) % 256; tmp=box[i];box[i]=box[j];box[j]=tmp; } // 核心加解密部分 for(a=j = i=0;i < stringlength;i++) { a=(a + 1) % 256; j=(j + box[a]) % 256; tmp=box[a];box[a]=box[j];box[j]=tmp; // 从密匙簿得出密匙进行异或,再转成字符 result.=chr(ord(string[i])(box[(box[a] + box[j]) % 256])); } if(operation == 'DECODE') { // 验证数据有效性,请看未加密明文的格式 if((substr(result, 0, 10) == 0 || substr(result, 0, 10) - time() > 0) && substr(result, 10, 16) == substr(md5(substr(result,26).keyb), 0, 16)) { return substr(result, 26); } else { return ''; } } else { // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因 // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码 return keyc.str_replace('=', '', base64_encode($result)); } }
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:blog.csdn.net/qq_24700495…