当前位置: 首页 > 知识库问答 >
问题:

Base64解码值中的字符串已损坏(Java),

祁晟
2023-03-14
  • base64编码字符串:yobic4fy
  • base64解码字符串(来自ASP页面):`àhsx(正确)
  • Base64解码字符串(来自JSP页面和Eclipse):^àhs?x(不正确)

Java/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。我不明白问题出在哪里。如有任何帮助,我们将不胜感激。

' 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: mark@shamedesigns.com
' Visit our website at: http://www.shamedesigns.com/
'

    Dim Base64Chars
    Base64Chars =   "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & _
            "abcdefghijklmnopqrstuvwxyz" & _
            "0123456789" & _
            "+/"


    ' 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字符串:?hs?x

解密的文本:foobír

所以,这里有些东西不对劲。事实上,对于Java,在解密方式上做一个更改就会返回foobar的正确解密文本。Java代码中的RC4解密采用int[]类型形式的密码。

public int[] decrypt(int[] ciphertext, byte[] key) throws Exception {
    return encrypt(ciphertext, key);
}
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;
}
String base64String = "yOBIc4FY";

byte[] decodedBase64Byte = Base64.decodeBase64(base64String);

int[] cipheredText =  convertToIntArray(decodedBase64Byte);
String base64String = "yOBIc4FY";

byte[] decodedBase64Byte = Base64.decodeBase64(base64String);

// ÈàHs?X
String decodedBase64String = new String(decodedBase64Byte, "ISO-8859-1");

int[] cipheredText =  convertToIntArray(decodedBase64String.getBytes());

共有1个答案

相诚
2023-03-14

yobic4fy的正确解码为6字节,具体为:

c8 e0 48 73 81 58

?hsx值可能只是忽略字符0x81作为不可打印。

证明:

y      O      B      I      c      4      F      Y
110010 001110 000001 001000 011100 111000 000101 011000

11001000 11100000 01001000 01110011 10000001 01011000
c8       e0       48       73       81       58
static void printByteArray(byte[] bytes) {
    for (byte b : bytes) {
        System.out.print(Integer.toHexString(b & 0xff) + ", ");
    }
    System.out.println();
}

public static void main(String[] args) {

    byte[] cipherBytes = Base64.getDecoder().decode("yOBIc4FY");
    printByteArray(cipherBytes); // c8, e0, 48, 73, 81, 58 - correct

    cipherBytes = new String(cipherBytes).getBytes();
    printByteArray(cipherBytes); // c8, e0, 48, 73, 3f, 58 - wrong
    // your results may vary depending on your default charset,
    // these are for windows-1250
}
 类似资料:
  • 我修改了一个phonegap插件。Java部分输出一个base64字符串: 然后我将它传递给某个Javascript,然后将字符串发送给服务器。我已经检查了.php文件接收到的字符串,base64字符串是相同的。然而,当我解码base64字符串时,它似乎已损坏。为了更好的示例,将此文本文件的内容复制到解码器中。 注意:当.php文件尝试解码它的数据:image/png;base64在前面时,我只是

  • 问题内容: 是否有仅使用JAVA 1.5 LIBRARIES来解码base64字符串的简便方法? 由于Windows和Mac OS X之间存在跨平台兼容性问题,我必须使用Java 1.5(仅Mac 10.5支持Java 1.6,低于10.5的所有内容均默认使用Java 1.5)。 对象“ sun.misc.Base64Decoder”在Java 6中存在,但在Java 5中不存在。 问题答案: 不

  • 我想将一个字符串编码成并通过套接字传输它,然后解码回来。 下面是我的代码,结果是“77+9x6s=” 有什么想法如何实现这一点吗?

  • 我一直在尝试在我的应用程序中实现GMAIL API,该应用程序是使用Swift5和Xcode构建的。我已经成功地检索到来自用户的电子邮件,但我无法从编码字符串中获得实际的文本。每当我尝试将这个base64编码的数据转换为普通字符串时,它都返回NIL。 这是绳子 stackoverflow的一些答案建议向string添加填充,但这也不起作用。

  • 为什么会发生这种事,有谁知道…??我做错了什么...

  • 我有一个Java类,我用GSON把它转换成字符串。张贴这个字符串是base64编码的(由于某种原因,我们不去那里:),当我解码回来,我失去了所有的json中的{和}字符。 例如:{“name”:“ABC”}解码并编码回名称ABC 我想要回我的旧数据,即我想要回{"name:"ABC"} 像上面这样简单的事情,内容丢失了 请帮忙