我正在从Classic ASP
页面发送base64 encoded string
页面到JSP
页面。在编码之前,该字符串是RC4
加密的。来自Base64的字符串解码值损坏(Java),
现在,我观察到,在ASP
页面内,编码和解码字符串base64
的工作正常。但是,JSP
页面上的base64 decoded string
不正确。我也尝试在Eclipse中解码字符串并得到相同的结果。它似乎与字符编码类型有关,但我正在努力确定究竟是什么问题。
- base64编码字符串:yOBIc4FY
- 的base64解码(从ASP页)字符串:ÈàHsX(正确)
- 的base64解码的字符串(从JSP页面和Eclipse):ÈàHsX? (不正确的)
爪哇/ JSP代码:
import org.apache.commons.codec.binary.Base64;
String base64String = "yOBIc4FY";
byte[] decodedBase64Byte = Base64.decodeBase64(base64String);
// ÈàHs?X
decodedBase64String = new String(decodedBase64Byte, "ISO-8859-1");
// ÈàHs?X
decodedBase64String = new String(decodedBase64Byte, "windows-1252");
// ??Hs?X
decodedBase64String = new String(decodedBase64Byte, "utf-8");
重申,正确的值应该是ÈàHsX
。我不明白是什么问题。任何帮助,将不胜感激。
谢谢。
更新
让我在此进一步阐述。
经典ASP中的RC4加密算法广泛普及,所以我不会浪费房地产在这里发布它。不过,我会在下面显示我使用'经典ASP'的base64 encoder/decoder
。
对于RC4,我使用的明文值是foobar。我正在使用的密钥是test。表面上,解码base64字符串应该返回密码。解密密码应该返回明文值。
' Functions to provide encoding/decoding of strings with Base64.
'
' Encoding: myEncodedString = base64_encode(inputString)
' Decoding: myDecodedString = base64_decode(encodedInputString)
'
' Programmed by Markus Hartsmar for ShameDesigns in 2002.
' Email me at: [email protected]
' Visit our website at: http://www.shamedesigns.com/
'
Dim Base64Chars
Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & _
"abcdefghijklmnopqrstuvwxyz" & _
"" & _
"+/"
' Functions for encoding string to Base64
Public Function base64_encode(byVal strIn)
Dim c1, c2, c3, w1, w2, w3, w4, n, strOut
For n = 1 To Len(strIn) Step 3
c1 = Asc(Mid(strIn, n, 1))
c2 = Asc(Mid(strIn, n + 1, 1) + Chr(0))
c3 = Asc(Mid(strIn, n + 2, 1) + Chr(0))
w1 = Int(c1/4) : w2 = (c1 And 3) * 16 + Int(c2/16)
If Len(strIn) >= n + 1 Then
w3 = (c2 And 15) * 4 + Int(c3/64)
Else
w3 = -1
End If
If Len(strIn) >= n + 2 Then
w4 = c3 And 63
Else
w4 = -1
End If
strOut = strOut + mimeencode(w1) + mimeencode(w2) + _
mimeencode(w3) + mimeencode(w4)
Next
base64_encode = strOut
End Function
Private Function mimeencode(byVal intIn)
If intIn >= 0 Then
mimeencode = Mid(Base64Chars, intIn + 1, 1)
Else
mimeencode = ""
End If
End Function
' Function to decode string from Base64
Public Function base64_decode(byVal strIn)
Dim w1, w2, w3, w4, n, strOut
For n = 1 To Len(strIn) Step 4
w1 = mimedecode(Mid(strIn, n, 1))
w2 = mimedecode(Mid(strIn, n + 1, 1))
w3 = mimedecode(Mid(strIn, n + 2, 1))
w4 = mimedecode(Mid(strIn, n + 3, 1))
If w2 >= 0 Then _
strOut = strOut + _
Chr(((w1 * 4 + Int(w2/16)) And 255))
If w3 >= 0 Then _
strOut = strOut + _
Chr(((w2 * 16 + Int(w3/4)) And 255))
If w4 >= 0 Then _
strOut = strOut + _
Chr(((w3 * 64 + w4) And 255))
Next
base64_decode = strOut
End Function
Private Function mimedecode(byVal strIn)
If Len(strIn) = 0 Then
mimedecode = -1 : Exit Function
Else
mimedecode = InStr(Base64Chars, strIn) - 1
End If
End Function
从内ASP,明文值被正确地从密码实现的:
明文:foobar的
密文:ÈàHsX
BASE64字符串:yOBIc4FY
解码base64字符串:ÈàHsX
解密正文:foobar的
然而,通过密码为Base64字符串JSP/Java中,JSP/Java的是这样的:
明文:(从ASP)
foobar的密文:ÈàHsX(从ASP)
BASE64字符串:yOBIc4FY
解码的base64字符串:EA HS X
解密文本:foobßr
所以,自己是不是加起来就在这里。实际上,对于Java,在解密解密过程中进行一次更改将返回正确的解密文本foobar
。 Java代码中的RC4解密采用类型为int[]
的密码。
public int[] decrypt(int[] ciphertext, byte[] key) throws Exception {
return encrypt(ciphertext, key);
}
换句话说,我必须将密码从String
类型转换为键入int[]
。我使用下面的功能来做到这一点:
public static int[] convertToIntArray(byte[] input)
{
int[] ret = new int[input.length];
for (int i = 0; i < input.length; i++)
{
ret[i] = input[i] & 0xff; // Range 0 to 255
}
return ret;
}
我有两种选择。我可以将base64字符串解码为类型byte[]
并解密,这将返回foobar
。
String base64String = "yOBIc4FY";
byte[] decodedBase64Byte = Base64.decodeBase64(base64String);
int[] cipheredText = convertToIntArray(decodedBase64Byte);
或者,我可以解码的base64字符串作为byte[]
类型,然后将其转换为键入String
,然后再返回到输入byte[]
到decrpyt,这将返回foobßr
。
String base64String = "yOBIc4FY";
byte[] decodedBase64Byte = Base64.decodeBase64(base64String);
// ÈàHs?X
String decodedBase64String = new String(decodedBase64Byte, "ISO-8859-1");
int[] cipheredText = convertToIntArray(decodedBase64String.getBytes());
我的猜测是那么原始字节序列是正确的,因为RC4解密函数成功返回foobar
。但是,当我将字节序列转换为某个字符编码集的字符串时,它将更改该值,最终以解密值foobßr
。
它仍然没有道理,那么为什么ASP和JSP/Java报告稍微不同的密码值? ASP将base64字符串或密码解码回明文值没有问题。我不知道这个问题是与ASP,JSP还是两者兼而有之。
您正在使用哪个Web服务器? Tomcat的? – rickz
是的,Tomcat for JSP。我也在Eclipse(JDK/JRE 1.6-1.8)中进行了本地测试,同样的问题。 – user3621633