c#.net内核中的等效AES加密代码
我有一个AES/CBC加密代码是用C写的。我必须用C转换这个代码# C代码:c#.net内核中的等效AES加密代码,c#,c,.net-core,openssl,cryptography,C#,C,.net Core,Openssl,Cryptography,我有一个AES/CBC加密代码是用C写的。我必须用C转换这个代码# C代码: EVP_CIPHER_CTX_init(&e_ctx); err = EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, NULL); err = EVP_CIPHER_CTX_set_padding(&e_ctx,EVP_CIPH_NO_PADDING); err = EVP_EncryptUpdate(&e_
EVP_CIPHER_CTX_init(&e_ctx);
err = EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, NULL);
err = EVP_CIPHER_CTX_set_padding(&e_ctx,EVP_CIPH_NO_PADDING);
err = EVP_EncryptUpdate(&e_ctx,cipher,&cipher_len,plain,plain_len);
err = EVP_EncryptFinal_ex(&e_ctx, cipher+cipher_len, &f_len);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
//aesAlg.IV = IV;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor();
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{ using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{ using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(data);
}
byte[] encrypted = msEncrypt.ToArray();
}
}
}
C#代码:
EVP_CIPHER_CTX_init(&e_ctx);
err = EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, NULL);
err = EVP_CIPHER_CTX_set_padding(&e_ctx,EVP_CIPH_NO_PADDING);
err = EVP_EncryptUpdate(&e_ctx,cipher,&cipher_len,plain,plain_len);
err = EVP_EncryptFinal_ex(&e_ctx, cipher+cipher_len, &f_len);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
//aesAlg.IV = IV;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor();
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{ using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{ using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(data);
}
byte[] encrypted = msEncrypt.ToArray();
}
}
}
但在这两种情况下,我得到的是不同的密文。钥匙是一样的。
而IV在C代码中不使用。所以也不要在c代码中使用。但我怀疑OpenSSL和.net API是否使用了一些默认的IV。C和C代码仅在IV中有所不同。在C代码中,EVP_EncryptInit_ex()
将NULL
作为第五个参数传递,这会导致零IV,即IV仅由0x00
值组成。相反,C代码使用在调用Aes.Create()
时创建的随机IV
因此,如果在C代码中应用零向量,则C代码在功能上与C代码相同。要执行此操作,请在行aesAlg.Key=Key
下方添加:
aesAlg.IV = new byte[16];
除此之外,两种代码使用相同的模式和相同的填充:
- 模式:在C代码中,
显式设置cbc模式,这是C代码中的默认模式EVP_aes_256_cbc()
- 填充:在C代码中,填充只是表面上被禁用。仅当第二个参数为
时,才禁用默认PKCS7填充。但后者并非如此,因为0
被定义为EVP\u CIPH\u NO\u PADDING
。因此C代码使用默认的PKCS7填充,这是C代码中的默认填充。0x100
C代码中未禁用的填充可能是由于在EVP\u CIPH\u NO\u padding()上下文中意外使用
EVP\u CIPHER\u CTX\u set\u padding()而导致的疏忽。根据文件规定,
适用于以下情况:EVP\u CIPH\u NO\u PADDING
但是,请注意,静态IV与零IV一样是不安全的。通常,每次加密都会生成一个随机的IV,因为它不是秘密的,所以会与密文一起发送(通常是串联的)。这是否回答了您的问题?您需要像C代码那样将模式设置为CBC并将填充设置为无。无填充将不起作用。将返回错误,如输入数据必须在块大小中。E是公钥和私钥。公钥随数据一起发送。如果发送串行数据,公钥有时是消息的开头。@jdweng这是关于AES的,AES只有一个密钥。请不要把事情搞混了。谢谢!!!将IV设置为零..会产生相同的结果。