我有一個在 PHP 中使用的加密函數function Encrypt(?string $Content, string $Key): string { return openssl_encrypt($Content, 'aes-256-gcm', $Key, OPENSSL_RAW_DATA, $IV = random_bytes(16), $Tag, '', 16) . $IV . $Tag;}搭配解密功能function Decrypt(?string $Ciphertext, string $Key): ?string { if (strlen($Ciphertext) < 32) return null; $Content = substr($Ciphertext, 0, -32); $IV = substr($Ciphertext, -32, -16); $Tag = substr($Ciphertext, -16); try { return openssl_decrypt($Content, 'aes-256-gcm', $Key, OPENSSL_RAW_DATA, $IV, $Tag); } catch (Exception $e) { return null; }}我將從加密函數加密的數據存儲到我的數據庫中,現在我試圖在 Go 中解密這些相同的值,但我得到了,但我cipher: message authentication failed無法弄清楚我遺漏了什么。c := []byte(`encrypted bytes of sorts`) // the bytes from the dbcontent := c[:len(c)-32]iv := c[len(c)-32 : len(c)-16]tag := c[len(c)-16:]block, err := aes.NewCipher(key[:32])if err != nil { panic(err.Error())}aesgcm, err := cipher.NewGCMWithNonceSize(block, 16)if err != nil { panic(err.Error())}fmt.Println(aesgcm.NonceSize(), aesgcm.Overhead()) // making sure iv and tag are both 16 bytesplaintext, err := aesgcm.Open(nil, iv, append(content, tag...), nil)if err != nil { panic(err.Error())}值得注意的是,我使用的密鑰不是 32 字節(它更大),因為我不知道所需的密鑰/應該是 32 字節,所以我不完全確定 PHP 正在用它做什么(就像將它截斷為 32 與使用具有 32 字節輸出的東西散列它與其他東西相比)。查看OpenGo 源代碼中的函數,看起來標簽應該是文本的最后一個“標簽大小”字節,所以這就是為什么我在解析片段后將標簽附加到密文。
1 回答

鳳凰求蠱
TA貢獻1825條經驗 獲得超4個贊
通常加密的消息看起來像IV+ciphertext+tag,而不是ciphertext+IV+tag。當一個人偏離慣例時,就會遇到各種各樣的問題:-)
你看到調用后iv 切片append(ciphertext, tag...)發生了什么嗎?您基本上iv用以下內容覆蓋了tag:
Before:
924b3ba4 18f49edc1757f3fe88adcaa7ec4c1e7d 15811fd0b712b0b091433073f6a38d7b
After:
924b3ba4 15811fd0b712b0b091433073f6a38d7b 15811fd0b712b0b091433073f6a38d7b
iv作為快速修復,在調用之前復制一份append():
iv := make([]byte, 16)
copy(iv, c[len(c)-32 : len(c)-16])
- 1 回答
- 0 關注
- 329 瀏覽
添加回答
舉報
0/150
提交
取消