英文:
How to encrypt a file so that OpenSSL can decrypt it without providing the IV manually
问题
我想用AES加密一个文件,就像openssl enc
命令一样,这样当我想解密它时就不需要手动提供IV。
英文:
I want to encrypt a file with AES the same way openssl enc
command does, so when I want to decrypt it there won't be need for providing IV manually.
答案1
得分: 2
为了解密一个AES加密的文件,你需要同时拥有密钥和初始化向量(IV)。IV并不是一个秘密,通常存储在加密文件中。
OpenSSL使用一个密钥派生函数,使用提供的密码和一个随机盐来生成这两个值。然后,在加密过程中,它将盐存储在文件头部,并添加*Salted__*前缀,以便在解密时可以与密码一起使用,生成相同的密钥和IV。
你可以使用以下代码进行解密:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"io"
"os"
"golang.org/x/crypto/pbkdf2"
)
func main() {
keySize := 32
password := []byte("TESTPASSWORD1234TESTPASSWORD1234")
bReader, err := os.Open("doc-encrypted.docx")
defer bReader.Close()
if err != nil {
panic(err)
}
header := make([]byte, 16)
if _, err := io.ReadFull(bReader, header); err != nil {
panic(err)
}
salt := header[8:16]
computed := pbkdf2.Key(password, salt, 10000, keySize+aes.BlockSize, sha256.New)
key := computed[:keySize]
iv := computed[keySize:]
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
stream := cipher.NewOFB(block, iv)
bWriter, err := os.Create("doc-decrypted.docx")
if err != nil {
panic(err)
}
defer bWriter.Close()
sReader := &cipher.StreamReader{S: stream, R: bReader}
if _, err := io.Copy(bWriter, sReader); err != nil {
panic(err)
}
}
你可以使用以下命令解密:
openssl enc -in doc-encrypted.docx -out doc-decrypted.docx -d -aes-256-ofb -pbkdf2 -pass pass:TESTPASSWORD1234TESTPASSWORD1234
请注意,这只是一个演示用途的代码,实际使用时需要进行适当的错误处理和安全性考虑。
英文:
In order to decrypt an AES encrypted file you need both key and IV. IV is not a secret and is usually store at the encrypted file.
OpenSSL uses a key derivation function to generate these two using the provided password and a random salt. then after encryption it stores the salt at the header of the file with Salted__ prefix, so at the decryption it could use it along with the password to produce the same key and IV.
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"io"
"os"
"golang.org/x/crypto/pbkdf2"
)
func main() {
keySize := 32;
// its only for demonstration purpose
password := []byte("TESTPASSWORD1234TESTPASSWORD1234");
bReader, err := os.Open("doc.docx")
defer bReader.Close();
if err != nil {
panic(err)
}
salt := make([]byte, 8)
if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
panic(err)
}
computed := pbkdf2.Key(password, salt, 10000, keySize + aes.BlockSize , sha256.New)
key := computed[:keySize]
iv := computed[keySize:]
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
stream := cipher.NewOFB(block, iv)
bWriter, err := os.Create("doc-encrypted.docx")
if err != nil {
panic(err)
}
defer bWriter.Close()
prefix := []byte("Salted__");
header := append(prefix[:], salt...);
bWriter.Write(header)
sWriter := &cipher.StreamWriter{S: stream, W: bWriter}
if _, err := io.Copy(sWriter, bReader); err != nil {
panic(err)
}
}
and you can decrypt it with openssl enc -in doc-encrypted.docx -out doc-decrypted.docx -d -aes-256-ofb -pbkdf2 -pass pass:TESTPASSWORD1234TESTPASSWORD1234
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论