How I can decode aes-256-cfb?
I have file encoded by aes-256-cfb, when I use openssl command
openssl enc -d -aes-256-cfb -salt -pbkdf2 -pass file:encpass -out x.txz -in encpkg
this file is decrypted without any problem,but when I try to decrypt this file by golang, I always get incorrect file, I don't know what my problem is and I hope to find help
my code:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"log"
"os"
)
func main() {
fiencpkg, err := os.ReadFile("encpkg")
if err != nil {
log.Println(err)
os.Exit(1)
}
fiencpass, err := os.ReadFile("encpass")
if err != nil {
log.Println(err)
os.Exit(1)
}
keyb := sha256.Sum256(fiencpass)
block, err := aes.NewCipher(keyb[:])
if err != nil {
panic(err)
}
if len(fiencpkg) < aes.BlockSize {
panic("data too short")
}
iv := fiencpkg[:aes.BlockSize]
decdata := fiencpkg[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(decdata, fiencpkg[aes.BlockSize:])
os.WriteFile("x_go.txz", decdata, 0777)
}
CodePudding user response:
The -pbkdf2 option in the OpenSSL statement causes the PBKDF2 key derivation to be used:
During encryption, a random 8 bytes salt is generated, and together with the password, the key and IV are determined using this key derivation.
Since the salt is needed for decryption, the OpenSSL statement concatenates salt and ciphertext and indicates this with the prefix Salted__
.
Thus, during decryption, salt and ciphertext must first be separated:
salt := fiencpkg[8:16]
ciphertext := fiencpkg[16:]
Then key and IV can be derived via PBKDF2 using e.g. the pbkdf2 package:
keyIv := pbkdf2.Key(fiencpass, salt, 10000, 48, sha256.New)
key := keyIv[0:32]
iv := keyIv[32:48]
Note the OpenSSL default values 10000 and SHA256 for iteration count and digest. Since the encryption was done with AES-256-CFB 48 bytes have to be generated (32 bytes for the key, 16 bytes for the IV).
After determining key and IV, decryption can be performed as usual.
Full code:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"log"
"os"
"golang.org/x/crypto/pbkdf2"
)
func main() {
fiencpkg, err := os.ReadFile("encpkg")
if err != nil {
log.Println(err)
os.Exit(1)
}
salt := fiencpkg[8:16]
ciphertext := fiencpkg[16:]
fiencpass, err := os.ReadFile("encpass")
if err != nil {
log.Println(err)
os.Exit(1)
}
keyIv := pbkdf2.Key(fiencpass, salt, 10000, 48, sha256.New)
key := keyIv[0:32]
iv := keyIv[32:48]
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ciphertext, ciphertext)
os.WriteFile("x_go.txz", ciphertext, 0777)
}