如何使用Bouncy Castle解密AES / CCM加密密文?

时间:2012-05-01 10:59:25

标签: c# aes bouncycastle encryption

加密

使用Stanford Javascript Crypto Library(SJCL)完成加密。下面是一个完整的加密示例,分为两部分。第一个是关于基于密码的密钥派生PBKDF2。在第二部分中,实际加密使用派生密钥和initialization vector(IV)进行。请注意,salt和IV是硬编码的,因此更容易提供C#解密解决方案。

// Key derivation…
var password = "password";
var salt = sjcl.codec.hex.toBits(
    "5f9bcef98873d06a" // Random generated with sjcl.random.randomWords(2, 0);
);                     // Hex encoded with sjcl.codec.hex.toBits(randomSalt);
var iterations = 1000;
var keySize = 128;
var encryptionKey = sjcl.misc.pbkdf2(password, salt, iterations, keySize);

// Encryption…
var blockCipher = new sjcl.cipher.aes(encryptionKey);
var plainText = sjcl.codec.utf8String.toBits("secret");
var iv = sjcl.codec.hex.toBits("8291ff107e798a29");
var adata = ""; // What is adata?
var tag = 64; // What is tag? I think it is authentication strength.
var cipherText = sjcl.mode.ccm.encrypt(blockCipher, plainText, iv, adata, tag);

encryptionKey变量的值:

  • SJCL位数组:[ -74545279, -553931361, -1590906567, 1562838103 ]
  • Hex已编码:fb8e8781defbad9fa12cb1395d270457
  • Base64已编码:+46Hgd77rZ+hLLE5XScEVw==

iv变量的值:

  • SJCL位数组:[ -2104361200, 2121894441 ]
  • 十六进制编码:8291ff107e798a29
  • Base64编码:gpH/EH55iik=

cipherText变量的值:

  • SJCL位数组:[ 1789401157, -1485204800, -440319203, 17593459146752 ]
  • 十六进制编码:6aa81845a77992c0e5c1431d4be2
  • Base64编码:aqgYRad5ksDlwUMdS+I=

问题

问题是:

如何使用Bouncy Castle解密密文?


在jbtule下面的帮助下工作解密示例

using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;

namespace SjclHelpers {

    public static class Encryption {

        /// <summary>Decrypts the cipher text.</summary>
        /// <param name="cipherText">The cipher text.</pararesm>
        /// <param name="key">The encryption key.</param>
        /// <param name="initializationVector">The IV.</param>
        /// <returns>The decrypted text.</returns>
        public static byte[] Decrypt(this byte[] cipherText,
            byte[] key, byte[] initializationVector) {
            var keyParameter = new KeyParameter(key);
            const int macSize = 64;
            var nonce = initializationVector;
            var associatedText = new byte [] {};
            var ccmParameters = new CcmParameters(
                keyParameter,
                macSize,
                nonce,
                associatedText);
            var ccmMode = new CcmBlockCipher(new AesFastEngine());
            var forEncryption = false;
            ccmMode.Init(forEncryption, ccmParameters);
            var plainBytes =
                new byte[ccmMode.GetOutputSize(cipherText.Length)];
            var res = ccmMode.ProcessBytes(
                cipherText, 0, cipherText.Length, plainBytes, 0);
            ccmMode.DoFinal(plainBytes, res);
            return plainBytes;
        }}}

我得到System.ArgumentException。我认为有人抱怨其中一个字节数组是短路的。

Boncy Castle可在NuGet网站上找到:http://nuget.org/packages/BouncyCastle


关于

AES / CCM解密解决方案将成为SjclHelpers CodePlex项目的一部分,并将作为NuGet包发布。

2 个答案:

答案 0 :(得分:2)

从我所看到的:

  1. Nonce应该是IV。
  2. 一般情况下,您使用的是AeadParameters而不是CcmParameters,但这可能仍然没问题,请确保不要使用ParametersWithIV将其包装
  3. associateText是可选的,因为如果需要,CCM可以验证与加密数据相关的未加密数据。您可能需要一个参数,因为它需要与sjcl adata相同,并且传输方法可以是任何东西。
  4. tagmacSize相同是正确的。
  5. DoFinal应为ccmMode.DoFinal(plainBytes, res);
  6. 为了安全起见,在解密之后,您应该将cipherText的最后一个(macSize / 8)字节与ccmMode.GetMac()进行比较,以检查身份验证。
  7. var plainBytes = new byte[ccmMode.GetOutputSize(cipherText.Length)]

答案 1 :(得分:0)

你不能用Bouncy Castle解密sjcl JSON。因为SJCL的预先计算表与Bouncy Castle的表不同。 我做了自己的图书馆。如果您仍在寻找解密解决方案,请试一试。 https://github.com/mebius1080p/SJCLDecryptor