代码之家  ›  专栏  ›  技术社区  ›  Leeish

如何将padbytes函数转换为coldfusion

  •  3
  • Leeish  · 技术社区  · 7 年前

    我在node中有以下代码,正在尝试转换为coldfusion:

    // a correct implementation of PKCS7. The rijndael js has a PKCS7 padding already implemented
    // however, it incorrectly pads expecting the phrase to be multiples of 32 bytes when it should pad based on multiples
    // 16 bytes. Also, every javascript implementation of PKCS7 assumes utf-8 char encoding. C# however is unicode or utf-16.
    // This means that chars need to be treated in our code as 2 byte chars and not 1 byte chars.
    function padBytes(string){
      const strArray = [...new Buffer(string, 'ucs2')];
    
      const need = 16 - ((strArray.length) % 16);
      for(let i = 0; i < need; i++) {
        strArray.push(need);
      }
    
      return Buffer.from(strArray);
    }
    

    我正试着理解这个函数到底在做什么来转换它。据我所知,它将字符串转换为utf-16(ucs2),然后为每个字符添加填充。但是,我不明白为什么 need 变量是它的值,也不是如何在cf中实现它。

    我也不明白为什么它只是一次又一次地将相同的值推送到数组中。首先,在我的示例脚本中,字符串是 2018-06-14T15:44:10Z testaccount 。字符串数组长度为64。我不知道如何达到甚至在CF。

    我尝试过字符编码,将其转换为二进制,然后将其转换为utf-16,但是对js函数的理解不够,无法在coldfusion中复制它。我觉得我丢失了一些编码。

    编辑:

    选择的答案解决了这个问题,但因为我最终试图使用输入数据进行加密,所以更简单的方法是完全不使用此函数,而是执行以下操作:

    <cfset stringToEncrypt = charsetDecode(input,"utf-16le") />
    <cfset variables.result = EncryptBinary(stringToEncrypt, theKey, theAlgorithm, theIV) />
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   SOS    7 年前

    更新:

    我们跟进了 chat 结果发现这个值最终与 encrypt() . 由于encrypt()已经(自动)处理填充,因此不需要自定义 padBytes() 功能。但是,它确实需要切换到不太常用的 encryptBinary() 函数来维护utf-16编码。普通的encrypt()函数只处理utf-8,这会产生完全不同的结果。

    Trycf.com Example:

    // Result with sample key/iv: P22lWwtD8pDrNdQGRb2T/w==
    result = encrypt("abc", theKey, theAlgorithm, theEncoding, theIV); 
    
    // Result Result with sample key/iv: LJCROj8trkXVq1Q8SQNrbA== 
    input = charsetDecode("abc", "utf-16le");
    result= binaryEncode(encryptBinary(input, theKey, theAlgorithm, theIV), "base64);
    

    它把字符串转换成utf-16 (UCS2)然后为每个字符添加填充。 …我觉得我丢失了一些编码。

    是的,第一部分似乎是将字符串解码为utf-16(或ucs2 slightly different )至于你错过了什么,你不是唯一的一个。我也没法让它工作直到我发现 this comment 这就解释了“utf-16”在bom之前。要省略bom,请根据需要的endianess使用“utf-16be”或“utf-16le”。

    为什么它只是一次又一次地将相同的值推送到数组中。

    因为这就是 PCKS7 padding . 它不使用诸如空或零之类的填充,而是计算需要多少字节填充。然后用那个号码 作为填充值 。例如,假设一个字符串需要额外的三个字节填充。pcks7追加值 3 -三次: "string" + "3" + "3" + "3" .

    其余代码在cf中类似。不幸的是,charsetdecode()的结果是不可变的。必须构建一个单独的数组来容纳填充,然后将两者合并。

    注意,此示例使用cf2016特定语法组合数组,但也可以使用简单的循环来代替

    功能:

    function padBytes(string text){
    
      var combined = [];
      var padding = [];
      // decode as utf-16
      var decoded = charsetDecode(arguments.text,"utf-16le");
    
      // how many padding bytes are needed?
      var need = 16 - (arrayLen(decoded) % 16);
      // fill array with any padding bytes
      for(var i = 0; i < need; i++) {
         padding.append(need);
      }
    
      // concatenate the two arrays
      // CF2016+ specific syntax. For earlier versions, use a loop 
      combined = combined.append(decoded, true);
      combined = combined.append(padding, true);
    
      return combined;
    }
    

    用途:

    result = padBytes("2018-06-14T15:44:10Z testaccount");
    writeDump(binaryEncode( javacast("byte[]", result), "base64"));
    
    推荐文章