Vin*_* Li 6 encryption base64 go
我有一个 go test 程序来从文件中读取加密内容并解密它,但它得到如下输出:
\n\n输入字节 0 处的非法 Base64 数据
\n\n如果我将加密内容硬编码在 golang 字符串变量中,它可以很好地解密。我在这里缺少什么?我在 stackoverflow 中搜索了类似的错误,有类似的报告,但与我遇到的问题不完全相同。测试代码如下:
\n\npackage 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}\nRun Code Online (Sandbox Code Playgroud)\n
您需要取消引用encrypted_text从扫描仪返回的内容。\n这是一个最小的示例
修改你的scanner.Scan()if 块看起来像这样
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 }\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n为什么你需要取消引用
\n
我猜你的文件test.txt包含原始字符串
\\xf2F\\xbc\\x15\\x9d\\xaf\\xceQ\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f\nRun Code Online (Sandbox Code Playgroud)\n\n当扫描仪从文件中读取此内容时,它将 a 读取\\为\\.
但是,当您像这样在代码中硬编码它时
\n\nencrypted_text = "\\xf2F\\xbc\\x15\\x9d\\xaf\\xce\xcf\x98\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f"\nRun Code Online (Sandbox Code Playgroud)\n\n您使用的是双引号",因此 a \\is\'ta \\。它解释转义序列。如果您要按如下方式使用反引号
encrypted_text = `\\xf2F\\xbc\\x15\\x9d\\xaf\\xce\xcf\x98\\xa3L(>%\\xa2\\x94\\x03_\\x99\\u007fG\\xd8\\v\\xbf\\t#u\\xf8:\\xc0D\\u007f`\nRun Code Online (Sandbox Code Playgroud)\n\n你会面临同样的问题。
\n\n解决方案是使用strconv.Unquote取消引用该字符串
\n\n另外,看看这个问题
\n