[英]Golang- AES Decryption is not returning same Text
我正在關注此文檔並嘗試使用 GoLang 實現簡單的 AES 加密和解密。 對於純文本,它工作正常,但是對於 UUID,它不起作用。 除了解決這個問題以及為什么會這樣。 這是我的示例代碼
package main
import (
"crypto/aes"
"encoding/hex"
"fmt"
)
func main() {
key := "thisis32bitlongpassphraseimusing"
pt := "a30a1777-e9f4-ed45-4755-add00172ebae"
c := EncryptAES([]byte(key), pt)
fmt.Println(pt)
fmt.Println(c)
DecryptAES([]byte(key), c)
}
func EncryptAES(key []byte, plaintext string) string {
c, err := aes.NewCipher(key)
CheckError(err)
out := make([]byte, len(plaintext))
c.Encrypt(out, []byte(plaintext))
return hex.EncodeToString(out)
}
func DecryptAES(key []byte, ct string) {
ciphertext, _ := hex.DecodeString(ct)
c, err := aes.NewCipher(key)
CheckError(err)
pt := make([]byte, len(ciphertext))
c.Decrypt(pt, ciphertext)
s := string(pt[:])
fmt.Println("DECRYPTED:", s)
}
func CheckError(err error) {
if err != nil {
panic(err)
}
}
這是 output
a30a1777-e9f4-ed45-4755-add00172ebae
e0f32a5bcf576754da4206cc967157ae0000000000000000000000000000000000000000
DECRYPTED: a30a1777-e9f4-ed
如您所見,UUID 的最后一部分正在消失。 我附上了一張快照,上面說它沒有正確解密最后一部分。 有誰知道這背后的原因? 我見過一個類似的問題,但不完全是一個問題。
您的代碼的問題是 AES 加密要求輸入是塊大小的倍數(AES-128 為 16 個字節),但是您要加密的 UUID(“a30a1777-e9f4-ed45-4755-add00172ebae” ) 是 36 字節長,它導致密碼錯誤。
解決此問題的一種方法是填充明文,使其長度是加密前塊大小的倍數。 Go 標准庫中有一個package 叫做crypto/padding ,它提供了給明文添加padding 的函數。
您可以像這樣修改 EncryptAES function:
func EncryptAES(key []byte, plaintext string) string {
c, err := aes.NewCipher(key)
CheckError(err)
plaintextBytes := []byte(plaintext)
// Add padding to plaintext
blockSize := c.BlockSize()
padding := blockSize - (len(plaintextBytes) % blockSize)
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
plaintextBytes = append(plaintextBytes, padtext...)
out := make([]byte, len(plaintextBytes))
c.Encrypt(out, plaintextBytes)
return hex.EncodeToString(out)
}
然后在 DecryptAES function 中,您可以在解密密文之前刪除填充,如下所示:
func DecryptAES(key []byte, ct string) {
ciphertext, _ := hex.DecodeString(ct)
c, err := aes.NewCipher(key)
CheckError(err)
pt := make([]byte, len(ciphertext))
c.Decrypt(pt, ciphertext)
//Remove padding
padLen := int(pt[len(pt)-1])
s := string(pt[:len(pt)-padLen])
fmt.Println("DECRYPTED:", s)
}
至於填充方案,您可能想嘗試像 pkcs#5 或 pkcs#7 這樣的填充方案。
如果您查看AES 分組密碼的頁面,您會發現aes.NewCipher
返回一個Block
,正如 Jake 在評論中提到的那樣。
現在,如果您 go 到該頁面,您會看到該頁面指出了各種模式,您可以使用這些模式從分組密碼中創建真實、安全的密碼。 塊密碼僅處理數據塊,在 AES 的情況下,數據塊始終為 128 位/16 字節。 所以這正是為什么在密文之后有所有那些零的原因,它加密了 16 個字節,就是這樣。 請注意,密文應始終看起來像隨機字節。
不幸的是,它沒有直接列出經過身份驗證的 (AEAD) 模式,因此也請查看此處。 也就是說,您可以看到CTR 模式在那里,包括示例,這是您鏈接到的問題 + 我的答案中缺少的主要思想。 您的代碼中沒有任何內容顯示操作模式,當然也不是計數器模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.