-
Notifications
You must be signed in to change notification settings - Fork 78
AES CFB can't decrypt when raw string's length more than 48 #29
Copy link
Copy link
Closed
Description
Hello,
I encountered an issue with the following code:
package main
import (
"bytes"
"crypto/aes"
stdcipher "crypto/cipher"
"encoding/base64"
"fmt"
"strings"
"github.com/dromara/dongle"
"github.com/dromara/dongle/crypto/cipher"
)
func main() {
key := []byte("dongle1234567890")
iv := []byte("1234567890123456")
c := cipher.NewAesCipher(cipher.CFB)
c.SetKey(key)
c.SetIV(iv)
c.SetPadding(cipher.PKCS7)
text := strings.Repeat("1", 48)
ciphertext := dongle.Encrypt.FromString(text).ByAes(c).ToBase64String()
plaintext := dongle.Decrypt.FromBase64String(ciphertext).ByAes(c).ToString()
fmt.Println(plaintext == text)
text = strings.Repeat("1", 49)
ciphertext = dongle.Encrypt.FromString(text).ByAes(c).ToBase64String()
plaintext = dongle.Decrypt.FromBase64String(ciphertext).ByAes(c).ToString()
fmt.Println(plaintext == text)
fmt.Println("---")
text = strings.Repeat("1", 48)
ciphertext = stdEncrypt(key, iv, text)
plaintext = stdDecrypt(key, iv, ciphertext)
fmt.Println(plaintext == text)
text = strings.Repeat("1", 49)
ciphertext = stdEncrypt(key, iv, text)
plaintext = stdDecrypt(key, iv, ciphertext)
fmt.Println(plaintext == text)
}
func pkcs7Padding(src []byte, blockSize int) []byte {
paddingSize := blockSize - len(src)%blockSize
paddingText := bytes.Repeat([]byte{byte(paddingSize)}, paddingSize)
return append(src, paddingText...)
}
func pkcs7UnPadding(src []byte) []byte {
if len(src) == 0 {
return []byte("")
}
n := len(src) - int(src[len(src)-1])
return src[0:n]
}
func stdEncrypt(key []byte, iv []byte, text string) string {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
plaintext := pkcs7Padding([]byte(text), block.BlockSize())
ciphertext := make([]byte, len(plaintext))
stream := stdcipher.NewCFBEncrypter(block, iv[:])
stream.XORKeyStream(ciphertext, plaintext)
return base64.RawURLEncoding.EncodeToString(ciphertext)
}
func stdDecrypt(key []byte, iv []byte, text string) string {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
ciphertext, err := base64.RawURLEncoding.DecodeString(text)
if err != nil {
panic(err)
}
plaintext := make([]byte, len(ciphertext))
stream := stdcipher.NewCFBDecrypter(block, iv[:])
stream.XORKeyStream(plaintext, ciphertext)
return string(pkcs7UnPadding(plaintext))
}golang version: go1.24.5 darwin/arm64
dongle version: v1.1.4
I expected to get:
true
true
---
true
true
But I actually get:
true
false
---
true
true
The OFB is same, and by the way, different input would got different results, such as
text = strings.Repeat("0", 48)
The result is
false
false
---
true
true
text = strings.Repeat("2", 48)
The result is
true
true
---
true
true
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels