【问题标题】:What is the C# equivalent of Java BouncyCastle AES decryption?Java BouncyCastle AES 解密的 C# 等价物是什么?
【发布时间】:2013-10-09 16:18:14
【问题描述】:

我有以下需要翻译成 c# 的 Java 代码:

public static byte[] encryptAES(byte[] toEncrypt, byte[] key,
                                boolean encrypte) throws Exception {

    Security.addProvider(new BouncyCastleProvider());

    byte[] iv = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                  (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                  (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                  (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };

    IvParameterSpec salt = new IvParameterSpec(iv);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");

    if (encrypte == false)
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),  salt);
    else
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"),  salt);

    byte[] result = cipher.doFinal(toEncrypt);
    return result;
}

你是如何做到的:

Security.addProvider(new BouncyCastleProvider());

什么是等价的:

IvParameterSpec salt = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");

【问题讨论】:

  • 感谢 SLaks。我试过了,但没有好的结果。对方给了我一个使用 BoucyCastle 的有效 Java 示例,所以我想我会使用它。 AESManaged 类中没有 PKCS5Padding。 (虽然我不认为这有什么区别)
  • @ntoskrnl 感谢这篇有趣的文章!!但是不,我不打算让别人做我的工作。我确实尝试了很多,首先使用 AESManaged,然后我请求了对方的技术帮助,对方刚刚给了我 Jave 代码,现在我只想让 BouncyCastle 工作......
  • 有一个 BouncyCastle c# 版本。尝试一下? bouncycastle.org/csharp

标签: c# java encryption cryptography bouncycastle


【解决方案1】:

试试这个。

根据http://social.msdn.microsoft.com/Forums/en-US/13a20d89-7d84-4f7d-8f5c-5ae108a7f5cf/des-encryption-padding-mode-pkcs5?forum=csharplanguagepkcs#5与pkcs#7相同。

public static byte[] EncryptDataAES(byte[] toEncrypt, byte[] key)
    {
        byte[] encryptedData;
        byte[] iv = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                                                        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };


        using (SymmetricAlgorithm aes = SymmetricAlgorithm.Create())
        {
            aes.Mode = CipherMode.CBC;
            aes.Key = key;
            aes.IV = iv;
            aes.Padding = PaddingMode.PKCS7;
            ICryptoTransform encryptor = aes.CreateEncryptor();
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, encryptor, CryptoStreamMode.Write))
                {
                    cStream.Write(toEncrypt, 0, toEncrypt.Length);
                    cStream.FlushFinalBlock();
                    encryptedData = mStream.ToArray();
                }
            }
        }
        return encryptedData;
    }

解密:

public static string DecryptDataAES(byte[] cipherText, byte[] key, byte[] iv)
        {
            string plaintext = null;

            using (Rijndael rijAlg = Rijndael.Create())
            {
                rijAlg.Key = key;
                rijAlg.IV = iv;

                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;
        }

使用它来解码您的密钥,该密钥是字节的十六进制表示。

public static byte[] StringToByteArray(String hex)
    {
        int NumberChars = hex.Length / 2;
        byte[] bytes = new byte[NumberChars];
        using (var sr = new StringReader(hex))
        {
            for (int i = 0; i < NumberChars; i++)
                bytes[i] =
                  Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
        }
        return bytes;
    }

【讨论】:

  • 我的问题是解密。我收到一个加密的(和 b64 编码的)字符串,必须解密它。我尝试了与您编写的内容类似的方法,但使用 AESManaged 类进行解密并得到“填充无效且无法删除”。使用 PKCS7 时出错。 (加密器使用 PKCS5,但正如您所说,这是一个子集)。使用无或零填充模式,我没有得到错误但错误的结果。
  • 你使用 Convert.FromBase64String(YOURSTRING); 转换字符串吗?获取字节数组?
  • 是的,这就是我使用的:byte[] cryptoBytes = Convert.FromBase64String(b64EncodedCryptoText);
  • 我收到以下错误:“填充无效,无法删除。”
  • 我发现你的问题关键不是 ascii 编码。它是密钥的十六进制表示。因此,使用我添加的方法将密钥解码为字节。所以使用: byte[] keyBytes = StringToByteArray(key);
猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2017-12-18
  • 2011-01-10
  • 2016-07-26
  • 2010-12-07
  • 2010-11-22
相关资源
最近更新 更多