在两台不同的机器上,CFML中的toBase64()函数输出不同。

8

最终编辑:问题已解决,将本地开发环境升级到railo 3.3.4.003即可解决该问题。


我需要使用RC4加密一些字符串并进行base64编码,但我遇到了这样的情况,同样的输入在两个不同的开发环境中会生成不同的输出。

例如,如果我有一个字符串:test2@mail.com
在一台机器(DEV-1)上,我得到:DunU+ucIPz/Z7Ar+HTw=
而在另一台机器(DEV-2)上,则是:DunU+ucIlZfZ7Ar+HTw=

首先,我通过此处找到的函数进行rc4加密。 接下来,我将其传递给:toBase64(my_rc4_encrypted_data,"iso-8859-1")

据我所知,rc4加密输出在两者上都相同(或者我漏掉了什么)。 以下是两台机器的SERVER变量以及加密函数。

这是我们必须面对的问题,还是有什么方法可以“妥善处理”它(缺乏更好的词汇)。 我担心将来这会给我带来麻烦,想知道是否可以避免。

编辑1: my_rc4_encrypted_data.getBytes()的输出如下: dev-1:

Native Array (byte[])
14--23--44--6--25-8-63-63--39--20-10--2-29-60

开发人员2:

Native Array (byte[])
14--23--44--6--25-8-63-63--39--20-10--2-29-60

(未向 getBytes() 传递编码方式)

DEV-1 (远程)

server.coldfusion
productname Railo
productversion  9,0,0,1

server.java
archModel   64
vendor  Sun Microsystems Inc.
version 1.6.0_26

server.os
arch    amd64
archModel   64
name    Windows Server 2008 R2
version 6.1

server.railo
version 3.3.2.002

server.servlet
name    Resin/4.0.18

DEV-2 (local)

server.coldfusion
productname     Railo
productversion  9,0,0,1

server.java
vendor  Oracle Corporation
version 1.7.0_01

server.os
arch    x86 
name    Windows 7
version 6.1

server.railo
version 3.2.2.000

server.servlet
name    Resin/4.0.18

RC4函数:

function RC4(strPwd,plaintxt) {
  var sbox = ArrayNew(1);
  var key = ArrayNew(1);
  var tempSwap = 0;
  var a = 0;
  var b = 0;
  var intLength = len(strPwd);
  var temp = 0;
  var i = 0;
  var j = 0;
  var k = 0;
  var cipherby = 0;
  var cipher = "";

  for(a=0; a lte 255; a=a+1) {  
    key[a + 1] = asc(mid(strPwd,(a MOD intLength)+1,1));
    sbox[a + 1] = a;
  }

  for(a=0; a lte 255; a=a+1) {  
    b = (b + sbox[a + 1] + key[a + 1]) Mod 256;   
    tempSwap = sbox[a + 1];
    sbox[a + 1] = sbox[b + 1];
    sbox[b + 1] = tempSwap;    
  }

  for(a=1; a lte len(plaintxt); a=a+1) {  
    i = (i + 1) mod 256;
    j = (j + sbox[i + 1]) Mod 256;    
    temp = sbox[i + 1];
    sbox[i + 1] = sbox[j + 1];
    sbox[j + 1] = temp;
    k = sbox[((sbox[i + 1] + sbox[j + 1]) mod 256) + 1];    
    cipherby = BitXor(asc(mid(plaintxt, a, 1)), k);
    cipher = cipher & chr(cipherby);      
  }
  return cipher;
}

1
仅为测试目的,您可以将它们都切换到运行相同的JVM版本,并查看是否有所不同。这是一个容易排除的变量。接下来是尝试在相同版本的Railo上运行,以防存在差异。 - Adam Cameron
2
好主意。但一定要在测试中使用相同的编码,即 String.getBytes(encoding)(编辑)如果省略它,则使用 jvm 默认值。这可能在您的两台机器上不同。嗯..那可能有关系。经过再次思考,尝试两种方式。 - Leigh
4
莉(Li)可能是对的 - RAILO-1393 导致了与字符集编码有关的toBase64更改,这发生在您正在使用的版本3.3.2.002和3.2.2.000之间的3.3.0.017中。 - Peter Boughton
2
不错,Peter。字符集的差异可以解释这个问题。 - Leigh
1
是的,似乎在版本之间处理传递的字符集的方式已经改变了。如果您将“iso-8859-1”作为参数传递,应该会得到两个不同的结果。我认为建议尽可能升级Railo。 - Stuart Wakefield
显示剩余8条评论
2个回答

2

Leigh写道:

但是请确保在您的测试中使用相同的编码,即String.getBytes(encoding)(编辑)如果省略,则使用jvm默认值。

Leigh是正确的 - RAILO-1393导致与字符集编码相关的toBase64的更改在3.3.0.017中发生,这介于您正在使用的3.3.2.002和3.2.2.000版本之间。


0
据我所知,rc4加密输出在两台机器上是相同的(或者我漏掉了什么)。下面是两台机器的SERVER变量以及加密函数。
我建议将输出保存到两个文件中,然后比较文件大小,甚至更好的方法是使用文件比较工具。Base64编码是将二进制数据转换为字符串数据的标准方法。
假设您的二进制文件在两台服务器上完全相同,在两台服务器上尝试将数据转换为base64,然后再次转换回二进制。我预测只有一台服务器(或者两台都不行)能够将数据转换回二进制。此时,您应该已经知道哪台服务器导致了问题,并可以进一步挖掘。
如果它们都可以将base64数据反转为二进制,并且两台服务器上的二进制都是正确的...嗯,我不确定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接