我正在尝试在Go中加密数据,并使用带有PKCS7填充的AES CBC模式在Angular中解密。但是当我尝试在Angular中解密数据时,它没有返回任何内容
Go代码:
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
)
func main() {
secret := []byte("28cEVB4BUE7GKNwjuRhN3szK5E3!&q*y")
data := []byte("Test")
encResult, err := Encrypt(data, secret)
fmt.Println("encResult", encResult)
fmt.Println("enc err", err)
// encrypted := "U2FsdGVkX1+LU7rE47VtIDwGIOsJa05BzOmAzQfdbVk="
result, err := Dncrypt(encResult, secret)
fmt.Println("decrypted result", result)
fmt.Println("decryption err", err)
}
/*CBC encryption Follow the example code of the golang standard library
But there is no padding inside, so make up
*/
// Use PKCS7 to fill, IOS is also 7
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
//aes encryption, filling the 16 bits of the key key, 24, 32 respectively corresponding to AES-128, AES-192, or AES-256.
func AesCBCEncrypt(rawData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//fill the original
blockSize := block.BlockSize()
rawData = PKCS7Padding(rawData, blockSize)
// Initial vector IV must be unique, but does not need to be kept secret
cipherText := make([]byte, blockSize+len(rawData))
//block size 16
iv := cipherText[:blockSize]
fmt.Println("iv", iv)
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
//block size and initial vector size must be the same
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(cipherText[blockSize:], rawData)
return cipherText, nil
}
func AesCBCDncrypt(encryptData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
blockSize := block.BlockSize()
if len(encryptData) < blockSize {
panic("ciphertext too short")
}
iv := encryptData[:blockSize]
encryptData = encryptData[blockSize:]
// CBC mode always works in whole blocks.
if len(encryptData)%blockSize != 0 {
panic("ciphertext is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
// CryptBlocks can work in-place if the two arguments are the same.
mode.CryptBlocks(encryptData, encryptData)
// Unfill
encryptData = PKCS7UnPadding(encryptData)
return encryptData, nil
}
func Encrypt(rawData, key []byte) (string, error) {
data, err := AesCBCEncrypt(rawData, key)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(data), nil
}
func Dncrypt(rawData string, key []byte) (string, error) {
data, err := base64.StdEncoding.DecodeString(rawData)
if err != nil {
return "", err
}
dnData, err := AesCBCDncrypt(data, key)
if err != nil {
return "", err
}
return string(dnData), nil
}
Angular/CryptoJs代码:
var CryptoJS = require("crypto-js");
var iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
var decrypted= CryptoJS.AES.decrypt("hKZ8CZgDopjCthfVZf7VmkSlX00nAJXpzNPRIUhGsO8=","28cEVB4BUE7GKNwjuRhN3szK5E3!&q*y",{iv:iv, padding: CryptoJS.pad.Pkcs7})
console.log("decrypted",decrypted.toString());
我从加密JS解密方法中得到一个空响应。
cryptoJS的iv值应该是多少?
试试这个,确保加密和解密使用相同密钥
//The get method is use for decrypt the value.
get(keys, value){
var key = CryptoJS.enc.Utf8.parse(keys);
var iv = CryptoJS.enc.Utf8.parse(keys);
var decrypted = CryptoJS.AES.decrypt(value, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
Go代码生成一个随机IV,并在带有PKCS7填充的CBC模式下使用AES-256执行加密。IV与密文IV|ciphertext
连接,结果是Base64编码的。密钥通过Utf8编码从给定的字符串生成。
注意,Go代码
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
用随机值初始化IV。所以IV的输出应该在那之后。由于它之前在发布的代码中打印,因此显示了零IV,但与使用的IV不一致
顺便说一下,对于解密,不需要显式输出,因为正如前面提到的,代码将IV和密文连接起来。
在CryptoJS代码中,使用了零IV,可能是因为Go代码中的输出不正确。相反,IV和密文必须分开。
此外,密钥作为字符串传递。这是不正确的,因为CryptoJS将字符串解释为密码并执行基于密码的密钥推导。相反,密钥必须作为WordArray
传递。
由于密钥是Go代码中编码的Utf8,因此必须应用Utf8编码器(另见另一个答案)。
CBC和PKCS7填充是默认值,可以指定,但不是必须指定。
以下CryptoJS代码中的密文是使用Go代码生成的:
js prettyprint-override">// Separate IV and ciphertext
var data = CryptoJS.enc.Base64.parse("WL7oDghTeEbjZ6QPeb/TGuDGijktQ4PZS7+wd0Ayu8Y="); // from Go code
var iv = CryptoJS.lib.WordArray.create(data.words.slice(0, 4)); // first 4 words = 16 bytes
var ct = CryptoJS.lib.WordArray.create(data.words.slice(4)); // rest
// Decrypt
var decrypted = CryptoJS.AES.decrypt(
{ciphertext: ct}, // alternatively as Base64 encoded string
CryptoJS.enc.Utf8.parse("28cEVB4BUE7GKNwjuRhN3szK5E3!&q*y"), // Utf8 encode key string
{iv:iv}
);
console.log("Decrypted: ", decrypted.toString(CryptoJS.enc.Utf8)); // Decrypted: Test
html lang-html prettyprint-override"><script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
一定有人知道,在网上没有任何一个工作的例子...
我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB
我希望有一个用C编写的程序,可以在没有openssl这样的大型库的帮助下,用AES-CBC对字符串进行编码/解码。 目标: 使用密码短语对字符串进行编码/解码: 因此,应用程序需要接受3个输入参数。。。 输入字符串(待编码)/或已编码字符串(待解码) 用于编码/解码字符串的密码 编码或解码指示器 我对C语言不熟悉(我可以用C#编码)。 我已经找到了https://github.com/kokke/
我遇到的情况是,JSON在PHP的中加密,需要在JAVA中解密。 此包含正确的数据,现在已解密。 现在,问题是当我试图做同样的事情在Java它不起作用:( 这是: 我已经访问了类似的问题,如 AES-256 CBC用php加密,用Java解密,反之亦然 openssl_在java中加密256个CBC原始_数据 无法在Java和PHP之间交换使用AES-256加密的数据 名单还在继续。。。。但是运气
我做了一个简单的文件加密/解密器。它将模式和要操作的文件作为参数。加密时,它生成随机字符串并使用该字符串加密文件。解密文件时,它会提示用户输入密码,并在解密时使用该密码。 我的问题是,解密时得到的不是明文,而是胡言乱语,尽管我小心翼翼地将相同的密钥写入输入。 非常感谢James K Polk提供的加密/解密代码!