The encryption is done with Stanford Javascript Crypto Library (SJCL). Below is a complete encryption example divided into two parts. The first is about password based key derivation with PBKDF2. In the second part the actual encryption happens with the derived key and an initialization vector (IV). Note that salt and IV is hard coded so that it is easier to provide a C# decryption solution.
// 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);
The value of the encryptionKey
variable:
[ -74545279, -553931361, -1590906567, 1562838103 ]
fb8e8781defbad9fa12cb1395d270457
+46Hgd77rZ+hLLE5XScEVw==
The value of the iv
variable:
[ -2104361200, 2121894441 ]
8291ff107e798a29
gpH/EH55iik=
The value of the cipherText
variable:
[ 1789401157, -1485204800, -440319203, 17593459146752 ]
6aa81845a77992c0e5c1431d4be2
aqgYRad5ksDlwUMdS+I=
The question is:
How can I decrypt the cipher text with Bouncy Castle?
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;
}}}
I get a System.ArgumentException
. I think it is complaining about that one of the byte arrays is to short.
Boncy Castle is available at the NuGet site at this location: http://nuget.org/packages/BouncyCastle.
The AES/CCM decryption solution will be part of the SjclHelpers project at CodePlex and will be released as a NuGet package.
From what I can see:
AeadParameters
instead of CcmParameters
but that might still be okay, for sure don't wrap it with ParametersWithIVassociateText
is optional, because CCM can authenticate unencrypted data that is related to your encrypted data if you need it. You probably need an argument as it needs to be the same as sjcl adata
and the method of transport could be anything.tag
and macSize
are the same.ccmMode.DoFinal(plainBytes, res);
macSize / 8
) bytes of the cipherText to ccmMode.GetMac()
to check the authentication.var plainBytes = new byte[ccmMode.GetOutputSize(cipherText.Length)]
You cannot decrypt sjcl JSON with Bouncy Castle. Because SJCL's pre-computed table is different from Bouncy Castle's one. I made own library. If you still looking for decrypting solution, have a try. https://github.com/mebius1080p/SJCLDecryptor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With