如何将padbytes函数转换为coldfusion

时间:2018-06-14 22:36:07

标签: node.js coldfusion

我在节点中有以下代码,我正在尝试转换为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 个答案:

答案 0 :(得分:1)

<强>更新

我们在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(或者是slightly different的UCS2)。至于你所缺少的东西,你并不是唯一的。在我找到this comment解释&#34; UTF-16&#34;之前,我无法让它工作。预先添加BOM。要省略BOM,请使用&#34; UTF-16BE&#34;或&#34; UTF-16LE&#34;取决于所需的结束。

  

为什么它只是一遍又一遍地将相同的值推入数组中。

因为这是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"));