golang输入字节0处的非法base64数据

Vin*_* Li 6 encryption base64 go

我有一个 go test 程序来从文件中读取加密内容并解密它,但它得到如下输出:

\n\n

输入字节 0 处的非法 Base64 数据

\n\n

如果我将加密内容硬编码在 golang 字符串变量中,它可以很好地解密。我在这里缺少什么?我在 stackoverflow 中搜索了类似的错误,有类似的报告,但与我遇到的问题不完全相同。测试代码如下:

\n\n
package main\n\nimport (\n"crypto/aes"\n"crypto/cipher"\n"crypto/rand"\n"encoding/base64"\n"errors"\n"fmt"\n"io"\n"bufio"\n"os"\n"log"\n\n)\n\n\nfunc check(e error) {\n    if e != nil {\n        panic(e)\n    }\n}\n\nfunc main() {\n    plaintext := []byte("textstring")\n    key := []byte("a very very very very very secre")\n    fmt.Printf("%s\\n", plaintext)\n\n    fh, err := os.Open("./test.txt")\n    check(err)\n    scanner := bufio.NewScanner(fh)\n    var encrypted_text string\n    if scanner.Scan() { //<==========READ FROM FILE\n    encrypted_text = scanner.Text()\n        fmt.Println("encrypted_text from file: ", encrypted_text)\n    } else { //<===========HARD CODE HERE\n        encrypted_text  = "\\xf2F\\xbc\\x15\\x9d\\xaf\\xce\xcf\x98\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f"\n        fmt.Println("encrypted_text hard coded: ", encrypted_text)\n    }\n\n    encrypted_byte  := []byte(encrypted_text)\n    fmt.Printf("encrypted_byte: %s\\n", encrypted_byte)\n    result, err := decrypt(key, encrypted_byte)\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Printf("result %s\\n", string(result))\n}\n\nfunc encrypt(key, text []byte) ([]byte, error) {\n    block, err := aes.NewCipher(key)\n    if err != nil {\n        return nil, err\n    }\n    b := base64.StdEncoding.EncodeToString(text)\n    ciphertext := make([]byte, aes.BlockSize+len(b))\n    iv := ciphertext[:aes.BlockSize]\n    if _, err := io.ReadFull(rand.Reader, iv); err != nil {\n        return nil, err\n    }\n    cfb := cipher.NewCFBEncrypter(block, iv)\n    cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))\n    return ciphertext, nil\n}\n\nfunc decrypt(key, text []byte) ([]byte, error) {\n    block, err := aes.NewCipher(key)\n    if err != nil {\n        return nil, err\n    }\n    if len(text) < aes.BlockSize {\n        return nil, errors.New("ciphertext too short")\n    }\n    iv := text[:aes.BlockSize]\n    text = text[aes.BlockSize:]\n    cfb := cipher.NewCFBDecrypter(block, iv)\n    cfb.XORKeyStream(text, text)\n    data, err := base64.StdEncoding.DecodeString(string(text))\n    if err != nil {\n        return nil, err\n    }\n    return data, nil\n}\n
Run Code Online (Sandbox Code Playgroud)\n

alg*_*ebe 5

您需要取消引用encrypted_text从扫描仪返回的内容。\n这是一个最小的示例

\n\n

修改你的scanner.Scan()if 块看起来像这样

\n\n
    if scanner.Scan() { //<==========READ FROM FILE\n        encrypted_text = scanner.Text()\n        fmt.Println("encrypted_text from file: ", encrypted_text)\n\n        // Unquoting, don\'t forget to import strconv !\n        encrypted_text, err := strconv.Unquote(`"` + encrypted_text + `"`)\n        check(err)\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

为什么你需要取消引用

\n
\n\n

我猜你的文件test.txt包含原始字符串

\n\n
\\xf2F\\xbc\\x15\\x9d\\xaf\\xceQ\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f\n
Run Code Online (Sandbox Code Playgroud)\n\n

当扫描仪从文件中读取此内容时,它将 a 读取\\\\.

\n\n

但是,当您像这样在代码中硬编码它时

\n\n
encrypted_text  = "\\xf2F\\xbc\\x15\\x9d\\xaf\\xce\xcf\x98\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f"\n
Run Code Online (Sandbox Code Playgroud)\n\n

您使用的是双引号",因此 a \\is\'ta \\。它解释转义序列。如果您要按如下方式使用反引号

\n\n
encrypted_text  = `\\xf2F\\xbc\\x15\\x9d\\xaf\\xce\xcf\x98\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f`\n
Run Code Online (Sandbox Code Playgroud)\n\n

你会面临同样的问题。

\n\n

解决方案是使用strconv.Unquote取消引用该字符串

\n\n

另外,看看这个问题

\n