【问题标题】:Decode base64 with white space使用空格解码 base64
【发布时间】:2018-08-30 10:36:24
【问题描述】:

我有一个 base64 编码的字符串,我正试图用 go 解密。该字符串包含应忽略的空格。 我正在尝试的示例代码:

s := "eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjEzZmU3MWQ0LWQxMGQtNDIyMC1hMjE2LTIwMDZkMWRkNGNiOCIsImFjc1RyY++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++W5zSUQiOiJkN2M0NWY5OS05NDc4LTQ0YTYtYjFmMi0xMDAwMDAwMDMzNjYiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0%3D"

out, err := base64.URLEncoding.DecodeString(s)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(string(out))

此代码返回:

输入字节 93 处的非法 base64 数据


更改字符串填充后,使用 StdEncoding 代替 URLEncoding:

s= strings.Replace(s, "%3D", "=", -1)
out, err := base64.StdEncoding.DecodeString(s)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(string(out))

输出将是:

{"threeDSServerTransID":"13fe71d4-d10d-4220-a216-2006d1dd4cb8","acsTrc���������������������������� ������������������������������������������������nsID”: "d7c45f99-9478-44a6-b1f2-100000003366","messageType":"CReq","messageVersion":"2.1.0","challengeWindowSize":"02"}


如何正确解密字符串?

【问题讨论】:

  • “我有一个 base64 编码的字符串”。不,你没有。如果你有一个,你可以毫无错误地解码它。你有别的东西。找出你实际拥有什么。
  • 这是一个base64编码的字符串。尝试使用此站点将正确解码字符串:base64decode.org
  • 我猜想字符串 supposed 使用tools.ietf.org/html/rfc4648 中描述的“URL 和文件名安全”编码,加号是某种无关信号. base64 的其他变体允许在编码中使用 +,或者将它们视为分隔符。

标签: string go base64 url-encoding


【解决方案1】:

您所拥有的很可能是从 URL 中“截断”的,并且是 URL 编码的形式。所以要得到一个Base64字符串,你必须先解码它,你可以使用url.PathUnescape()

获得未转义的字符串后,您可以使用base64.StdEncoding 编码器对其进行解码。请注意,仅仅因为它是 / 是 URL 的一部分,这并不能使它成为使用 Base64 的 URL 安全版本的字母表的 base64 字符串。

中间的+ 标志实际上只是“垃圾”。他们一开始就不应该在那里,所以仔细检查你是如何得到你的输入的,但是现在他们在那里,你必须删除它们。为此,您可以使用strings.Replace()

解码无效输入的最终代码:

s := "eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjEzZmU3MWQ0LWQxMGQtNDIyMC1hMjE2LTIwMDZkMWRkNGNiOCIsImFjc1RyY++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++W5zSUQiOiJkN2M0NWY5OS05NDc4LTQ0YTYtYjFmMi0xMDAwMDAwMDMzNjYiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0%3D"
s = strings.Replace(s, "+", "", -1)
var err error
if s, err = url.PathUnescape(s); err != nil {
    panic(err)
}

out, err := base64.StdEncoding.DecodeString(s)
if err != nil {
    panic(err)
}
fmt.Println(string(out))

完整输出(在Go Playground 上尝试):

{"threeDSServerTransID":"13fe71d4-d10d-4220-a216-2006d1dd4cb8",
   "acsTransID":"d7c45f99-9478-44a6-b1f2-100000003366","messageType":"CReq",
    "messageVersion":"2.1.0","challengeWindowSize":"02"}

请注意,+ 符号是标准 Base64 字母表中的有效符号,您甚至可以在不删除 + 符号的情况下解码 Base64,但随后您会在结果。

【讨论】:

    【解决方案2】:

    输入字符串有三个问题

    首先是中间的+号

    第二个结尾是垃圾(一个url编码的+)

    第三个字符串似乎不是有效的 Base64

    去掉中间的加号,找到开始和结束的索引,新建一个字符串 要在末尾删除垃圾,请提前终止字符串(在固定字符串的索引 249 处)

    固定字符串的索引 148 处的字符串还有一个问题,我猜这是由于数据错误

    但下面的代码片段展示了如何克服前两件事

    package main
    
    import (
        "fmt"
        "encoding/base64"
        "strings"
    )
    
    func main() {
        s := "eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjEzZmU3MWQ0LWQxMGQtNDIyMC1hMjE2LTIwMDZkMWRkNGNiOCIsImFjc1RyY++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++W5zSUQiOiJkN2M0NWY5OS05NDc4LTQ0YTYtYjFmMi0xMDAwMDAwMDMzNjYiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0%3D"
    
    
        a:=strings.Index(s,"+")
        b:=strings.LastIndex(s,"+")+1
    
        fixed:=s[0:a] + s[b:249]
        out, err := base64.StdEncoding.DecodeString(fixed)
        if err != nil {
            fmt.Println(err)
            fmt.Println(fixed)
    
        }
        fmt.Println(a,b)
        fmt.Println(String(out))
    
    }
    

    【讨论】:

    • 也许也很有趣:删除 + 符号并添加 = 代替如果 %3D,然后使用 UrlEncoding 进行解码和重新编码会得到一个完全不同的字符串,以“ZXlKMGFISmxaVVJUVT”开头
    猜你喜欢
    • 2015-07-14
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多