本帖最后由 TottyAndBaty 于 2013-08-30 23:43:38 编辑

解决方案 »

  1.   

    js 代码部分
    68 strbuf[i] =chr(ord(strbuf[i]) ^ (box[(box[a] + box[j]) % 256]))
    这个 strbuf 是数组吗?
    无论从
    21 strbuf = Base64.decode(str);
    还是
    36 strbuf = str;
    上看,strbuf 都是字符串
    那么 strbuf[i] = 'x' 这样写是无效的,虽然不报错
    同样 ord(strbuf[i]) 也是不能返回正确值的对应 ord(strbuf[i]) 的 js 是
    strbuf.charCodeAt(i)对应 chr(n) 的 js 是
    String.fromCharCode(n)没有认真去看你提供的php同名函数,但至少你的 js 取值、赋值部分已经就出问题了另外:
    DZ 的发行版是分 utf-8 和 gbk 的
    由于字符内码的原因,utf-8 版中的 Authcode 编码结果是不能在 gbk 版中正确解码的(解出的还是utf-8的)
    当然如果不含有中文是没有问题的,这一点你在测试的时候一定要注意那个 Base64 类也是针对 utf-8 编码的。如果 php 端不是 utf-8 的,你也不能得到相同的结果
      

  2.   

    不好意思,疏忽了。发错了版本。这段代码是我最后修正的结果:
     function authcode(str, operation, key, expiry) {
    var operation = operation ? operation : 'DECODE';
    var key = key ? key : '';
    var expiry = expiry ? expiry : 0;

    var ckey_length = 4;
    key = md5(key);

    // 密匙a会参与加解密
    var keya = md5(key.substr(0, 16));
    // 密匙b会用来做数据完整性验证
    var keyb = md5(key.substr(16, 16));
    // 密匙c用于变化生成的密文
    var keyc = ckey_length ? (operation == 'DECODE' ? str.substr(0, ckey_length): md5(microtime()).substr(-ckey_length)) : '';
    // 参与运算的密匙
    var cryptkey = keya+md5(keya+keyc);

     
      var string="";
    if(operation == 'DECODE') {
    string =Base64.decode(str.substr(ckey_length));
    }
    else {
     
    expiry = expiry ? expiry + time() : 0;
    tmpstr = expiry.toString();
    if(tmpstr.length>=10)
            string = tmpstr.substr(0,10)+md5(str+keyb).substr(0, 16)+str;
        else {
        var count = 10 - tmpstr.length;
            for(var i=0;i<count;i++) {
             tmpstr = '0'+tmpstr;
            } 
            string = tmpstr+md5(str+keyb).substr(0, 16)+str;
         }
            
    }
     
    var box = new Array(256);
    for(var i=0; i < 256; i++) {
    box[i] = i;
    }
    var rndkey = new Array();
    // 产生密匙簿
    for(var i=0; i < 256; i++) {  
        rndkey[i] = cryptkey.charCodeAt(i % cryptkey.length);
    }
    // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度  
    for(var j = i = 0; i < 256; i++) {  
        j = (j + box[i] + rndkey[i]) % 256;  
        tmp = box[i];  
        box[i] = box[j];  
        box[j] = tmp;  
    }


    // 核心加解密部分
     
    var result = '';
    for(var a = j = i = 0; i < string.length; i++) {
        a = (a + 1) % 256;
        j = (j + box[a]) % 256;
        tmp = box[a];
        box[a] = box[j];
        box[j] = tmp;
    result+=String.fromCharCode(string.charCodeAt(i) ^ (box[(box[a] + box[j]) % 256]));
    }
     
     
    if(operation == 'DECODE') {
     var s="";
    if((result.substr(0, 10) == 0 || result.substr( 0, 10) - time() > 0) && result.substr(10, 16) == md5(result.substr(26)+keyb).substr(0, 16)) {
        s = result.substr(26);
    }  
    }
    else {
    var s = Base64.encode(result);
    var regex = new RegExp('=', "g");
    s = s.replace(regex, '');
    s = keyc+s;
    } return s;
    }
    这里基本上没采用替代版的CHR,ORD,等,都用的JS只带的。我的测试页面编码都是UTF-8编码。这里的Base64.encode与php的base64_encode结果一样。前文说的ord,chr 都有提供JS版本的。chr:http://phpjs.org/functions/chr/ord:http://phpjs.org/functions/ord/
      

  3.   

    原本放在源码的加密解密数据,你现在用JS来实现,那么问一下,密匙你准备怎么处理?直接放在JS里么?