簡體   English   中英

Golang-AES 解密不返回相同的文本

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM