Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Wednesday, August 28, 2013 9:10 AM | 2 votes
Hello,
I'm having some difficulty decrypt data that was encrypted in javascript.
When I debug in C# I can't see the message decrypted.
I can provide more information if necessary.
Below is the code
Javascript:
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
var key = CryptoJS.enc.Utf8.parse('7061737323313233');
var iv = CryptoJS.enc.Utf8.parse('7061737323313233');
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("It works"), "Secret Passphrase", key,
{
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase", key, {
keySize: 128 / 8, iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
var options = { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 };
var encrypted = CryptoJS.AES.encrypt("It works", "Secret Passphrase", options);
var seg = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
var enc = encrypted;
var enckey = encrypted.key;
var encsalt = encrypted.salt;
var enciv = encrypted.iv;
alert('Encrypted :' + encrypted);
alert('Key :' + encrypted.key);
alert('Salt :' + encrypted.salt);
alert('iv :' + encrypted.iv);
alert('Decrypted : ' + decrypted);
alert('utf8 = ' + decrypted.toString(CryptoJS.enc.Utf8));
alert(seg);
</script>
Results Javascript:
//enc: U2FsdGVkX19jUqTCz/gGd8JqXhyshwRtGnIwIpXN2Zg=
//enckey: 4536538a2f826d756115ceed14569e9eefe97a4c83dadc5b176b5af535a73148
//enciv: 6352a4c2cff80677
//encsalt: c984599f97b3abfe3d127a7d25b40303
//seg: wmpeHKyHBG0acjAilc3ZmA==
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace bfDemoService
{
public class Codec
{
public static string DecryptStringAES()
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
string DataToEncrypt = "It works";
//Settings
myRijndael.Mode = CipherMode.CBC;
myRijndael.Padding = PaddingMode.PKCS7;
myRijndael.FeedbackSize = 128;
byte[] keybytes = Convert.FromBase64String("4536538a2f826d756115ceed14569e9eefe97a4c83dadc5b176b5af535a73148");
byte[] iv = Convert.FromBase64String("6352a4c2cff80677");
//DECRYPT FROM CRIPTOJS
byte[] encrypted = Convert.FromBase64String("U2FsdGVkX19jUqTCz/gGd8JqXhyshwRtGnIwIpXN2Zg=");
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes(encrypted, keybytes, iv);
return roundtrip;
}
}
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
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))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Padding = PaddingMode.PKCS7;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// 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(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
}
}
All replies (8)
Monday, September 2, 2013 3:13 PM âś…Answered
crypto-js uses OpenSSL key derivation to generate the iv and key from the passphrase. Internally this involves some non-standard use of MD5 and other techniques. You can duplicate this process in .NET by using the OpenSSL library (Nuget install-package openssl). The salt must be exactly 8-bytes and this, along with the magic phrase "Salted__" for a total of 16-bytes must be prepended and sent along with the encrypted bytes.
In the OpenSSL library see the CipherContext objects's Crypt method.
Quent
Wednesday, August 28, 2013 3:21 PM | 5 votes
Hi,
When you look at your code you can see that in the javascript function you are using the passphrase in c# you are not, also some differences in how you get your key and iv, last but not least in your javascript you use the encrypted variable twice, basically ignoring the first result.
So I cleaned it up and got the following code working on my machine:
Javascript:
<script>
var key = CryptoJS.enc.Utf8.parse('7061737323313233');
var iv = CryptoJS.enc.Utf8.parse('7061737323313233');
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("It works"), key,
{
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
alert('Encrypted :' + encrypted);
alert('Key :' + encrypted.key);
alert('Salt :' + encrypted.salt);
alert('iv :' + encrypted.iv);
alert('Decrypted : ' + decrypted);
alert('utf8 = ' + decrypted.toString(CryptoJS.enc.Utf8));
</script>
javascript result:
Encrypted :+Ijpt1GDVgM4MqMAQUwf0Q==
Key :37303631373337333233333133323333
Salt :undefined
iv :37303631373337333233333133323333
Decrypted : 497420776f726b73
utf8 = It works
c#
namespace MvcApplication6
{
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public static class Codec
{
public static string DecryptStringAES()
{
var keybytes = Encoding.UTF8.GetBytes("7061737323313233");
var iv = Encoding.UTF8.GetBytes("7061737323313233");
//c# encrrption
var encryptStringToBytes = EncryptStringToBytes("It works", keybytes, iv);
// Decrypt the bytes to a string.
var roundtrip = DecryptStringFromBytes(encryptStringToBytes, keybytes, iv);
//DECRYPT FROM CRIPTOJS
var encrypted = Convert.FromBase64String("+Ijpt1GDVgM4MqMAQUwf0Q==");
var decriptedFromJavascript = DecryptStringFromBytes(encrypted, keybytes, iv);
return string.Format(
"roundtrip reuslt:{0}{1}Javascript result:{2}",
roundtrip,
Environment.NewLine,
decriptedFromJavascript);
}
private static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
{
throw new ArgumentNullException("cipherText");
}
if (key == null || key.Length <= 0)
{
throw new ArgumentNullException("key");
}
if (iv == null || iv.Length <= 0)
{
throw new ArgumentNullException("key");
}
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged())
{
//Settings
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.PKCS7;
rijAlg.FeedbackSize = 128;
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
private static byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
{
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length <= 0)
{
throw new ArgumentNullException("key");
}
if (iv == null || iv.Length <= 0)
{
throw new ArgumentNullException("key");
}
byte[] encrypted;
// Create a RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged())
{
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.PKCS7;
rijAlg.FeedbackSize = 128;
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
}
}
I do hope that this is a sample and you are not going to use the javascript as is. Just putting your key in there defeats the purpose of encryption.
Hope this helps,
Here to learn and share. Please tell if an answer was helpful or not at all. This adds value to the answers and enables me to learn more.
Thursday, August 29, 2013 9:35 AM
Hi KeesDijk,
Thank you for your response.
In the previous post I forgot to mention that I want to encrypt in javascript with passphrase and decrypt in C# using the same passphrase and results cryptojs, that's why I use the passphrase in javascript, in C# does not know how to do this operation.
Can you help me please?
Thank you!
Thursday, August 29, 2013 10:50 AM
Please check this code sample from this thread:
using System;using System.IO;using System.Security.Cryptography;using System.Text;namespace ConsoleApplication1_Encryption_Rijn{ class Program { static void Main(string[] args) { Encoding byteEncoder = Encoding.Default; byte[] rijnKey = byteEncoder.GetBytes("abcdefg_abcdefg_abcdefg_abcdefg_"); byte[] rijnIV = byteEncoder.GetBytes("abcdefg_abcdefg_"); String message = "Attack begins at dawn!"; String encryption = EncryptIt(message, rijnKey, rijnIV); String decryption = DecryptIt(encryption, rijnKey, rijnIV); Console.WriteLine("Message: {0}", message); Console.WriteLine("Encryption: {0}", encryption); Console.WriteLine("Decryption: {0}", decryption); } private static String EncryptIt(String s, byte[] key, byte[] IV) { String result; RijndaelManaged rijn = new RijndaelManaged(); rijn.Mode = CipherMode.ECB; rijn.Padding = PaddingMode.Zeros; using (MemoryStream msEncrypt = new MemoryStream()) { using (ICryptoTransform encryptor = rijn.CreateEncryptor(key, IV)) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { swEncrypt.Write(s); } } } result = Convert.ToBase64String(msEncrypt.ToArray()); } rijn.Clear(); return result; } private static String DecryptIt(String s, byte[] key, byte[] IV) { String result; RijndaelManaged rijn = new RijndaelManaged(); rijn.Mode = CipherMode.ECB; rijn.Padding = PaddingMode.Zeros; using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(s))) { using (ICryptoTransform decryptor = rijn.CreateDecryptor(key, IV)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader swDecrypt = new StreamReader(csDecrypt)) { result = swDecrypt.ReadToEnd(); } } } } rijn.Clear(); return result; } }}
Caillen
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.
Thursday, August 29, 2013 11:23 AM
Hello Caillen,
Thanks for your suggestion.
However, when encrypt in the javascript 4 variables are presented: iv, key, encrypted and salt
In the code you sent there is no variable salt, i think the salt plus passphrase create the key and iv but I'm not sure, can you help me with this issue?
Thank you.
Sunday, December 10, 2017 9:03 AM
Thanks , can you please share the vice-versa of this? I mean Encryption in C# and Decryption in Javascript.
Thursday, August 9, 2018 12:28 PM
Working Thank you :-)
Friday, August 2, 2019 11:26 PM
Thank you very much. After spending more than 3 hours trying to get this to work, your code just saved my day. Just a couple of hints:
a) At least in the current version of CryptoJS, the encrypt() method now returns an object, so to get the actual encoded string, you need to call toString() method.
b) The value returned by the toString() method is a base64 string, so in your C# code you need to take that in consideration:
var originalPwd = Convert.FromBase64String(encodedPwd);var roundtrip = DecryptStringFromBytes(originalPwd, keybytes, iv);
Victor Espina Rancagua, Chile