c#.net core 中的等效 AES 加密代码

Equivalent AES encryption code in c# .net core

我有一个用 C 编写的 AES/CBC 加密代码。我必须在 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_ctx,cipher,&cipher_len,plain,plain_len); 
err = EVP_EncryptFinal_ex(&e_ctx, cipher+cipher_len, &f_len);

C#代码:

  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 代码中不使用 IV。所以也不要在 c# 代码中使用。但我怀疑 OpenSSL 和 .net API.

使用了一些默认 IV

C 和 C# 代码 在 IV 中不同。在 C 代码中,EVP_EncryptInit_ex()NULL 作为第 5 个参数传递,这导致 IV 为零,即仅由 0x00 值组成的 IV。相反,C# 代码使用在调用 Aes.Create() 时创建的随机 IV。

因此,如果在 C# 代码中应用零向量,则 C# 代码在功能上与 C 代码相同。为此,请在行下方添加 aesAlg.Key = key:

aesAlg.IV = new byte[16];

除此之外,两个代码都使用 same 模式和 same padding:

  • Mode:在C代码中,EVP_aes_256_cbc()显式设置CBC模式,即C#代码中的default模式。
  • 填充:在 C 代码中,填充仅表面上 禁用。 EVP_CIPHER_CTX_set_padding() 仅当第二个参数为 0 时才禁用默认的 PKCS7 填充。但是后者就不是这样了,因为EVP_CIPH_NO_PADDING被定义为0x100。所以C代码使用默认的PKCS7 padding,也就是C#代码中的default padding
    在 C 代码中未禁用填充可能是由于在 EVP_CIPHER_CTX_set_padding() 的上下文中意外使用 EVP_CIPH_NO_PADDING 造成的疏忽。根据文档,EVP_CIPH_NO_PADDING 应用于 EVP_CIPHER_meth_set_flags().
  • 的上下文中

如果添加以上行以便在 C# 代码中使用零向量,则 C 和 C# 代码在我的机器上为相同的输入数据生成相同的密文。

但是请注意,静态 IV 与零 IV 一样是不安全的。通常每次加密都会生成一个随机 IV,因为它不是秘密的,所以它与密文一起发送(通常是串联的)。