示例代码PHP / C#AES加密-随机IV

问题描述 投票:0回答:1

我找到了应该在PHP和C#中工作的AES加密/解密实现:https://odan.github.io/2017/08/10/aes-256-encryption-and-decryption-in-php-and-csharp.html

但是,在此示例中,IV始终为0,这不好。因此,正如作者所建议的,我使用openssl_random_pseudo_bytes()函数:

  $ivlen = openssl_cipher_iv_length($method);
  $iv = openssl_random_pseudo_bytes($ivlen);

但是,现在的问题是,我必须将IV存储在某个地方,以便C#应用程序可以将其用于解密。我的想法是对它进行base64_encode编码,然后将其添加到加密的消息中,并用“:”将两者分开,以便我可以简单地拆分字符串,然后base64在C#中对其进行解码并可以使用IV。但是,这不起作用。这是代码:

public string DecryptString(string cipherText, byte[] key, byte[] iv)
{
    // Instantiate a new Aes object to perform string symmetric encryption
    Aes encryptor = Aes.Create();

    encryptor.Mode = CipherMode.CBC;

    // Set key and IV
    byte[] aesKey = new byte[32];
    Array.Copy(key, 0, aesKey, 0, 32);
    encryptor.Key = aesKey;
    encryptor.IV = iv;

    // Instantiate a new MemoryStream object to contain the encrypted bytes
    MemoryStream memoryStream = new MemoryStream();

    // Instantiate a new encryptor from our Aes object
    ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

    // Instantiate a new CryptoStream object to process the data and write it to the 
    // memory stream
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

    // Will contain decrypted plaintext
    string plainText = String.Empty;

    try {
        // Convert the ciphertext string into a byte array
        byte[] cipherBytes = Convert.FromBase64String(cipherText);

        // Decrypt the input ciphertext string
        cryptoStream.Write(cipherBytes, 0, cipherBytes . Length);

        // Complete the decryption process
        cryptoStream.FlushFinalBlock();

        // Convert the decrypted data from a MemoryStream to a byte array
        byte[] plainBytes = memoryStream.ToArray();

        // Convert the decrypted byte array to string
        plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
    } finally {
        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();
    }

    // Return the decrypted data as a string
    return plainText;
}

这就是我尝试使用加密消息前的IV调用函数的方法:

private void btnDecrypt_Click(object sender, EventArgs e)
        {
            string encrypted = txtEncrypted.Text;
            string password = txtPW.Text;
            string[] temp = encrypted.Split(":".ToCharArray());
            string iv_str = temp[0];
            encrypted = temp[1];
            SHA256 mySHA256 = SHA256Managed.Create();
            byte[] key = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(password));
            iv_str = Encoding.Default.GetString(Convert.FromBase64String(iv_str));
            byte[] iv = Encoding.ASCII.GetBytes(iv_str);

            txtDecrypted.Text = this.DecryptString(encrypted, key, iv); 
        }

不起作用。它会解密某些内容,但这只是胡言乱语,而不是我在PHP中加密的消息。我认为这与静脉输液有关。

c# php aes
1个回答
0
投票

@@ Topaco:非常感谢您...现在我明白了我的错误。现在可以与生成的IV一起使用。顺便说一下,关于加密强度的另外两个问题:

  1. 是否可以使用以下函数来生成IV(出于某种原因GenerateIV()无效):

    byte [] iv =新的字节[16];随机rnd =新的Random();rnd.NextBytes(iv);

  2. 我在用户密码中添加了一个随机生成的盐,因此密钥是用户密码和盐的哈希值。我还将盐和现在随机生成的IV一起添加到消息中。然后在解密过程中,我使用前置的盐和用户输入的密钥。到目前为止工作。但这会削弱加密吗?不,对吧?

非常感谢。

//编辑:代码格式不起作用,不知道为什么。

© www.soinside.com 2019 - 2024. All rights reserved.