Reputation: 5264
I have a AES/CBC encryption code written in C. I have to convert this code in C#
C Code:
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);
C# code:
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();
}
}
}
But in both the case I am getting different ciphertext. While the key was the same. While IV is not used in C code. So not using in c# code as well. But I doubt there is some default IV used by the OpenSSL and .net API.
Upvotes: 1
Views: 1744
Reputation: 49121
The C and C# code differ only in the IV. In the C code, EVP_EncryptInit_ex()
passes a NULL
as 5th parameter, which results in a zero IV, i.e. an IV consisting only of 0x00
values. In contrast, the C# code uses a random IV created when Aes.Create()
is called.
The C# code is therefore functionally identical to the C code if a zero vector is applied in the C# code. To do this, add below the line aesAlg.Key = key
:
aesAlg.IV = new byte[16];
Apart from that, both codes use the same mode and the same padding:
EVP_aes_256_cbc()
explicitly sets the CBC mode, which is the default mode in the C# code.EVP_CIPHER_CTX_set_padding()
disables the default PKCS7 padding only if the 2nd parameter is 0
. But the latter is not the case, because EVP_CIPH_NO_PADDING
is defined as 0x100
. So the C code uses the default PKCS7 padding, which is the default padding in the C# code.EVP_CIPH_NO_PADDING
in the context of EVP_CIPHER_CTX_set_padding()
. According to the documentation, EVP_CIPH_NO_PADDING
is applied in the context of EVP_CIPHER_meth_set_flags()
.If the above line is added so that a zero vector is used in the C# code, the C and C# code produce the same ciphertext for identical input data on my machine.
Note, however, that a static IV, like a zero IV, is insecure. Usually a random IV is generated for each encryption, which, since it is not secret, is sent along with the ciphertext (typically concatenated).
Upvotes: 3