【问题标题】:Equivalent AES encryption code in c# .net corec# .net core 中的等效 AES 加密代码
【发布时间】:2021-08-14 16:44:50
【问题描述】:

我有一个用 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(); 
                        } 
                    } 
                }

但在这两种情况下,我都会得到不同的密文。虽然钥匙是一样的。 虽然 IV 未在 C 代码中使用。所以也不要在 c# 代码中使用。但我怀疑 OpenSSL 和 .net API 使用了一些默认的 IV。

【问题讨论】:

  • 这能回答你的问题吗? AES-256-CBC in .NET Core (C#)
  • 您需要像 C 代码一样将模式设置为 CBC,并将填充设置为 None。
  • 无填充将不起作用。将返回错误,例如输入数据必须在块大小中
  • 有公钥和私钥。公钥与数据一起发送。如果您要发送串行数据,公钥有时是消息的开头。
  • @jdweng 这是关于 AES 的,AES 只有一个密钥。请不要混淆问题。

标签: c# c .net-core openssl cryptography


【解决方案1】:

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 填充:

  • 模式:在C代码中,EVP_aes_256_cbc()明确设置了CBC模式,这是C#代码中的默认模式。
  • 填充:在 C 代码中,填充只是表面上禁用。仅当第二个参数为 0 时,EVP_CIPHER_CTX_set_padding() 才会禁用默认的 PKCS7 填充。但后者并非如此,因为EVP_CIPH_NO_PADDING 被定义为0x100。所以 C 代码使用默认的 PKCS7 填充,也就是 C# 代码中的 default 填充。
    在 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,因为它不是秘密的,所以它与密文(通常是连接的)一起发送。

【讨论】:

  • 谢谢!!!将 IV 设置为零..产生相同的结果。
猜你喜欢
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多