I want to decrypt text using the crypto.js library in an Angular application that is encrypted using AES encryption with the .NET System.Security.Cryptography library.
To encrypt using C# I use the following method:
private void FileEncrypt(string inputFile, string password)
{
byte[] salt = GenerateSalt();
byte[] passwords = Encoding.UTF8.GetBytes(password);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;//aes 256 bit encryption c#
AES.BlockSize = 128;//aes 128 bit encryption c#
AES.Padding = PaddingMode.PKCS7;
var key = new Rfc2898DeriveBytes(passwords, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CFB;
using (FileStream fsCrypt = new FileStream(inputFile + ".aes", FileMode.Create))
{
fsCrypt.Write(salt, 0, salt.Length);
using (CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
{
byte[] buffer = new byte[1048576];
int read;
while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
cs.Write(buffer, 0, read);
}
}
}
}
}
the GenerateSalt() method generates a cryptographically strong sequence of random byte values.
And to decrypt the following:
private void FileDecrypt(string inputFileName, string outputFileName, string password)
{
byte[] passwords = Encoding.UTF8.GetBytes(password);
byte[] salt = new byte[32];
using (FileStream fsCrypt = new FileStream(inputFileName, FileMode.Open))
{
fsCrypt.Read(salt, 0, salt.Length);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;//aes 256 bit encryption c#
AES.BlockSize = 128;//aes 128 bit encryption c#
AES.Padding = PaddingMode.PKCS7;
var key = new Rfc2898DeriveBytes(passwords, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CFB;
using (CryptoStream cryptoStream = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read))
{
using (FileStream fsOut = new FileStream(outputFileName.Replace(".aes",""), FileMode.Create))
{
int read;
byte[] buffer = new byte[1048576];
while ((read = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
{
fsOut.Write(buffer, 0, read);
}
}
}
}
}
To do a decryption test in angular using the crypto.js library, I used the following code:
convertText(conversion:string) {
var C = CryptoJS;
if (conversion=="encrypt") {
this.conversionEncryptOutput = CryptoJS.AES.encrypt(this.plainText.trim(), this.encPassword.trim()).toString();
}
else {
var C = CryptoJS;
this.conversionDecryptOutput = CryptoJS.AES.decrypt(
this.encryptText.toString(),
this.decPassword.trim(), {
mode: C.mode.CFB,
padding: C.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
}
}
I get the following error when trying to decrypt a pre-encrypted text using the C# method
enter image description here
ERROR Error: Malformed UTF-8 data
at Object.stringify (core.js:523:1)
at WordArray.init.toString (core.js:278:1)
at AppComponent.convertText (app.component.ts:36:14)
at AppComponent_Template_button_click_37_listener (app.component.html:39:74)
at executeListenerWithErrorHandling (core.js:15327:1)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:15365:1)
at HTMLButtonElement.<anonymous> (platform-browser.js:561:1)
at _ZoneDelegate.invokeTask (zone.js:406:1)
at Object.onInvokeTask (core.js:28679:1)
at _ZoneDelegate.invokeTask (zone.js:405:1)
I've been trying to encrypt and decrypt strings in by AES and C# in an interoperable way. My client application is a Node server that communicates with vendor's API is in dot NET.
The vendor uses these methods for encrypting and decrypting the strings:
public static string Encrypt(string data, string key)
{
string IV = key.Substring(0, 16);
byte[] iv = Encoding.UTF8.GetBytes(IV);
byte[] array;
using(Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using(MemoryStream memoryStream = new MemoryStream())
{
using(CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using(StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(data);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
public static string Decrypt(string data, string key)
{
string IV = key.Substring(0, 16);
byte[] iv = Encoding.UTF8.GetBytes(IV);
byte[] buffer = Convert.FromBase64String(data);
using(Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using(MemoryStream memoryStream = new MemoryStream(buffer))
{
using(CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using(StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
I tried for example crypto-js for decrypting the strings, but I cannot make it work:
const encryptedText = CryptoJS.enc.Base64.parse(base64Value)
const encrypted2 = encryptedText.toString(CryptoJS.enc.Base64);
const decrypt2 = CryptoJS.AES.decrypt(encrypted2, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt2.toString(CryptoJS.enc.Utf8)) // (also tried various other encodings, Utf16, Utf16LE and others)
The following Node.js code should work correctly with your .NET code.
We're using the algorithm aes-256-cbc to match the mode used in the C# example.
const crypto = require("crypto");
const Algorithm = "aes-256-cbc";
function encrypt(plainText, key, iv, outputEncoding = "base64") {
const cipher = crypto.createCipheriv(Algorithm, key, iv);
const output = Buffer.concat([cipher.update(plainText), cipher.final()]).toString(outputEncoding);
return output.replace('+', '-').replace('/', '_').replace('=', '');
}
function decrypt(cipherText, key, iv, outputEncoding = "utf8") {
cipherText = Buffer.from(cipherText, "base64");
const cipher = crypto.createDecipheriv(Algorithm, key, iv);
return Buffer.concat([cipher.update(cipherText), cipher.final()]).toString(outputEncoding);
}
const KEY = 'KFmnMAPzP!g#6Dy5HD?JSgYC9obE&m#m';
const IV = KEY.slice(0,16);
// Taking the output from our C# sample...
const encrypted = 'SORoNS48u0KniiANU3Y9Mw==';
console.log("Encrypted (base64):", encrypted);
const decrypted = decrypt(encrypted, KEY, IV)
console.log("Decrypted:", decrypted);
The equivalent C# code is below:
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
public class Program
{
public static void Main()
{
var str = Encrypt("test", "KFmnMAPzP!g#6Dy5HD?JSgYC9obE&m#m");
Console.WriteLine("Encrypted: " + str);
Console.WriteLine("Decrypted: " + Decrypt(str, "KFmnMAPzP!g#6Dy5HD?JSgYC9obE&m#m"));
}
public static string Encrypt(string data, string key)
{
string IV = key.Substring(0, 16);
byte[] iv = Encoding.UTF8.GetBytes(IV);
byte[] array;
using(Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using(MemoryStream memoryStream = new MemoryStream())
{
using(CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using(StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(data);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
public static string Decrypt(string data, string key)
{
string IV = key.Substring(0, 16);
byte[] iv = Encoding.UTF8.GetBytes(IV);
byte[] buffer = Convert.FromBase64String(data);
using(Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using(MemoryStream memoryStream = new MemoryStream(buffer))
{
using(CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using(StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
}
The output for the C# code is:
Encrypted: SORoNS48u0KniiANU3Y9Mw==
Decrypted: test
The Node.js code then decrypts this (using the same key and IV):
Encrypted (base64): SORoNS48u0KniiANU3Y9Mw=
Decrypted: test
Since you are using NodeJS, it makes sense to use the crypto module of NodeJS instead of CryptoJS (see the other answer). CryptoJS is of course also possible. Then the following must be considered:
In the JavaScript code, CBC mode has to be used, and key and IV must be passed as WordArray to CryptoJS.AES.decrypt(). The ciphertext can be passed Base64 encoded, CryptoJS implicitly converts this to a CipherParams object.
CryptoJS applies CBC and PKCS#7 padding by default, so these do not need to be explicitly specified (but may of course).
The ciphertext in the following example was generated with the C# code and can be decrypted with the following CryptoJS code:
const ciphertext = 'yKiV9TBw3eNt2QvK1kdXaw==';
const keyStr = "01234567890123456789012345678901"; // 32 bytes -> AES-256
const key = CryptoJS.enc.Utf8.parse(keyStr);
const IV = CryptoJS.enc.Utf8.parse(keyStr.substr(0, 16));
const decrypted = CryptoJS.AES.decrypt(ciphertext, key, {iv: IV}); // apply default: CBC and PKCS#7 padding
console.log(decrypted.toString(CryptoJS.enc.Utf8)); // Hello world!
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
Regarding security:
It's insecure to use the key (or a part of it) as IV. Instead, a random IV should be generated for each encryption. This is not secret and is passed together with the ciphertext, in general concatenated.
Also the generation of the key from a text reduces security (even with correct size the value range is reduced). More secure would be to use a reliable key derivation function like PBKDF2 if a text/passphrase is involved.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I can't seem to find a nice clean example of using AES 128 bit encryption.
Does anyone have some sample code?
If you just want to use the built-in crypto provider RijndaelManaged, check out the following help article (it also has a simple code sample):
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx
And just in case you need the sample in a hurry, here it is in all its plagiarized glory:
using System;
using System.IO;
using System.Security.Cryptography;
namespace RijndaelManaged_Example
{
class RijndaelExample
{
public static void Main()
{
try
{
string original = "Here is some data to encrypt!";
// Create a new instance of the RijndaelManaged
// class. This generates a new key and initialization
// vector (IV).
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Original: {0}", original);
Console.WriteLine("Round Trip: {0}", roundtrip);
}
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}
}
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("IV");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decryptor 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;
}
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("IV");
// 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;
}
}
}
I've recently had to bump up against this again in my own project - and wanted to share the somewhat simpler code that I've been using, as this question and series of answers kept coming up in my searches.
I'm not going to get into the security concerns around how often to update things like your Salt and Initialization Vector - that's a topic for a security forum, and there are some great resources out there to look at. This is simply a block of code to implement AesManaged in C#.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Your.Namespace.Security {
public static class Cryptography {
#region Settings
private static int _iterations = 2;
private static int _keySize = 256;
private static string _hash = "SHA1";
private static string _salt = "aselrias38490a32"; // Random
private static string _vector = "8947az34awl34kjq"; // Random
#endregion
public static string Encrypt(string value, string password) {
return Encrypt<AesManaged>(value, password);
}
public static string Encrypt<T>(string value, string password)
where T : SymmetricAlgorithm, new() {
byte[] vectorBytes = GetBytes<ASCIIEncoding>(_vector);
byte[] saltBytes = GetBytes<ASCIIEncoding>(_salt);
byte[] valueBytes = GetBytes<UTF8Encoding>(value);
byte[] encrypted;
using (T cipher = new T()) {
PasswordDeriveBytes _passwordBytes =
new PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);
cipher.Mode = CipherMode.CBC;
using (ICryptoTransform encryptor = cipher.CreateEncryptor(keyBytes, vectorBytes)) {
using (MemoryStream to = new MemoryStream()) {
using (CryptoStream writer = new CryptoStream(to, encryptor, CryptoStreamMode.Write)) {
writer.Write(valueBytes, 0, valueBytes.Length);
writer.FlushFinalBlock();
encrypted = to.ToArray();
}
}
}
cipher.Clear();
}
return Convert.ToBase64String(encrypted);
}
public static string Decrypt(string value, string password) {
return Decrypt<AesManaged>(value, password);
}
public static string Decrypt<T>(string value, string password) where T : SymmetricAlgorithm, new() {
byte[] vectorBytes = GetBytes<ASCIIEncoding>(_vector);
byte[] saltBytes = GetBytes<ASCIIEncoding>(_salt);
byte[] valueBytes = Convert.FromBase64String(value);
byte[] decrypted;
int decryptedByteCount = 0;
using (T cipher = new T()) {
PasswordDeriveBytes _passwordBytes = new PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);
cipher.Mode = CipherMode.CBC;
try {
using (ICryptoTransform decryptor = cipher.CreateDecryptor(keyBytes, vectorBytes)) {
using (MemoryStream from = new MemoryStream(valueBytes)) {
using (CryptoStream reader = new CryptoStream(from, decryptor, CryptoStreamMode.Read)) {
decrypted = new byte[valueBytes.Length];
decryptedByteCount = reader.Read(decrypted, 0, decrypted.Length);
}
}
}
} catch (Exception ex) {
return String.Empty;
}
cipher.Clear();
}
return Encoding.UTF8.GetString(decrypted, 0, decryptedByteCount);
}
}
}
The code is very simple to use. It literally just requires the following:
string encrypted = Cryptography.Encrypt(data, "testpass");
string decrypted = Cryptography.Decrypt(encrypted, "testpass");
By default, the implementation uses AesManaged - but you could actually also insert any other SymmetricAlgorithm. A list of the available SymmetricAlgorithm inheritors for .NET 4.5 can be found at:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.symmetricalgorithm.aspx
As of the time of this post, the current list includes:
AesManaged
RijndaelManaged
DESCryptoServiceProvider
RC2CryptoServiceProvider
TripleDESCryptoServiceProvider
To use RijndaelManaged with the code above, as an example, you would use:
string encrypted = Cryptography.Encrypt<RijndaelManaged>(dataToEncrypt, password);
string decrypted = Cryptography.Decrypt<RijndaelManaged>(encrypted, password);
I hope this is helpful to someone out there.
Look at sample in here..
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=VS.100).aspx#Y2262
The example on MSDN does not run normally (an error occurs) because there is no initial value of Initial Vector(iv) and Key. I add 2 line code and now work normally.
More details see below:
using System.Windows.Forms;
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace AES_TESTER
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
string original = "Here is some data to encrypt!";
MessageBox.Show("Original: " + original);
// Create a new instance of the RijndaelManaged
// class. This generates a new key and initialization
// vector (IV).
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
StringBuilder s = new StringBuilder();
foreach (byte item in encrypted)
{
s.Append(item.ToString("X2") + " ");
}
MessageBox.Show("Encrypted: " + s);
// Decrypt the bytes to a string.
string decrypted = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
MessageBox.Show("Decrypted: " + decrypted);
}
}
catch (Exception ex)
{
MessageBox.Show("Error: {0}", ex.Message);
}
}
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.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// 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;
}
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;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// 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;
}
}
}
Using AES or implementing AES? To use AES, there is the System.Security.Cryptography.RijndaelManaged class.
For a more complete example that performs key derivation in addition to the AES encryption, see the answer and links posted in Getting AES encryption to work across Javascript and C#.
EDIT
a side note: Javascript Cryptography considered harmful. Worth the read.
//Code to encrypt Data :
public byte[] encryptdata(byte[] bytearraytoencrypt, string key, string iv)
{
AesCryptoServiceProvider dataencrypt = new AesCryptoServiceProvider();
//Block size : Gets or sets the block size, in bits, of the cryptographic operation.
dataencrypt.BlockSize = 128;
//KeySize: Gets or sets the size, in bits, of the secret key
dataencrypt.KeySize = 128;
//Key: Gets or sets the symmetric key that is used for encryption and decryption.
dataencrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);
//IV : Gets or sets the initialization vector (IV) for the symmetric algorithm
dataencrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);
//Padding: Gets or sets the padding mode used in the symmetric algorithm
dataencrypt.Padding = PaddingMode.PKCS7;
//Mode: Gets or sets the mode for operation of the symmetric algorithm
dataencrypt.Mode = CipherMode.CBC;
//Creates a symmetric AES encryptor object using the current key and initialization vector (IV).
ICryptoTransform crypto1 = dataencrypt.CreateEncryptor(dataencrypt.Key, dataencrypt.IV);
//TransformFinalBlock is a special function for transforming the last block or a partial block in the stream.
//It returns a new array that contains the remaining transformed bytes. A new array is returned, because the amount of
//information returned at the end might be larger than a single block when padding is added.
byte[] encrypteddata = crypto1.TransformFinalBlock(bytearraytoencrypt, 0, bytearraytoencrypt.Length);
crypto1.Dispose();
//return the encrypted data
return encrypteddata;
}
//code to decrypt data
private byte[] decryptdata(byte[] bytearraytodecrypt, string key, string iv)
{
AesCryptoServiceProvider keydecrypt = new AesCryptoServiceProvider();
keydecrypt.BlockSize = 128;
keydecrypt.KeySize = 128;
keydecrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);
keydecrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);
keydecrypt.Padding = PaddingMode.PKCS7;
keydecrypt.Mode = CipherMode.CBC;
ICryptoTransform crypto1 = keydecrypt.CreateDecryptor(keydecrypt.Key, keydecrypt.IV);
byte[] returnbytearray = crypto1.TransformFinalBlock(bytearraytodecrypt, 0, bytearraytodecrypt.Length);
crypto1.Dispose();
return returnbytearray;
}
http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt
using System.Security.Cryptography;
using System.IO;
public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
Try this code, maybe useful.
1.Create New C# Project and add follows code to Form1:
using System;
using System.Windows.Forms;
using System.Security.Cryptography;
namespace ExampleCrypto
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string strOriginalData = string.Empty;
string strEncryptedData = string.Empty;
string strDecryptedData = string.Empty;
strOriginalData = "this is original data 1234567890"; // your original data in here
MessageBox.Show("ORIGINAL DATA:\r\n" + strOriginalData);
clsCrypto aes = new clsCrypto();
aes.IV = "this is your IV"; // your IV
aes.KEY = "this is your KEY"; // your KEY
strEncryptedData = aes.Encrypt(strOriginalData, CipherMode.CBC); // your cipher mode
MessageBox.Show("ENCRYPTED DATA:\r\n" + strEncryptedData);
strDecryptedData = aes.Decrypt(strEncryptedData, CipherMode.CBC);
MessageBox.Show("DECRYPTED DATA:\r\n" + strDecryptedData);
}
}
}
2.Create clsCrypto.cs and copy paste follows code in your class and run your code. I used MD5 to generated Initial Vector(IV) and KEY of AES.
using System;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
namespace ExampleCrypto
{
public class clsCrypto
{
private string _KEY = string.Empty;
protected internal string KEY
{
get
{
return _KEY;
}
set
{
if (!string.IsNullOrEmpty(value))
{
_KEY = value;
}
}
}
private string _IV = string.Empty;
protected internal string IV
{
get
{
return _IV;
}
set
{
if (!string.IsNullOrEmpty(value))
{
_IV = value;
}
}
}
private string CalcMD5(string strInput)
{
string strOutput = string.Empty;
if (!string.IsNullOrEmpty(strInput))
{
try
{
StringBuilder strHex = new StringBuilder();
using (MD5 md5 = MD5.Create())
{
byte[] bytArText = Encoding.Default.GetBytes(strInput);
byte[] bytArHash = md5.ComputeHash(bytArText);
for (int i = 0; i < bytArHash.Length; i++)
{
strHex.Append(bytArHash[i].ToString("X2"));
}
strOutput = strHex.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return strOutput;
}
private byte[] GetBytesFromHexString(string strInput)
{
byte[] bytArOutput = new byte[] { };
if ((!string.IsNullOrEmpty(strInput)) && strInput.Length % 2 == 0)
{
SoapHexBinary hexBinary = null;
try
{
hexBinary = SoapHexBinary.Parse(strInput);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
bytArOutput = hexBinary.Value;
}
return bytArOutput;
}
private byte[] GenerateIV()
{
byte[] bytArOutput = new byte[] { };
try
{
string strIV = CalcMD5(IV);
bytArOutput = GetBytesFromHexString(strIV);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return bytArOutput;
}
private byte[] GenerateKey()
{
byte[] bytArOutput = new byte[] { };
try
{
string strKey = CalcMD5(KEY);
bytArOutput = GetBytesFromHexString(strKey);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return bytArOutput;
}
protected internal string Encrypt(string strInput, CipherMode cipherMode)
{
string strOutput = string.Empty;
if (!string.IsNullOrEmpty(strInput))
{
try
{
byte[] bytePlainText = Encoding.Default.GetBytes(strInput);
using (RijndaelManaged rijManaged = new RijndaelManaged())
{
rijManaged.Mode = cipherMode;
rijManaged.BlockSize = 128;
rijManaged.KeySize = 128;
rijManaged.IV = GenerateIV();
rijManaged.Key = GenerateKey();
rijManaged.Padding = PaddingMode.Zeros;
ICryptoTransform icpoTransform = rijManaged.CreateEncryptor(rijManaged.Key, rijManaged.IV);
using (MemoryStream memStream = new MemoryStream())
{
using (CryptoStream cpoStream = new CryptoStream(memStream, icpoTransform, CryptoStreamMode.Write))
{
cpoStream.Write(bytePlainText, 0, bytePlainText.Length);
cpoStream.FlushFinalBlock();
}
strOutput = Encoding.Default.GetString(memStream.ToArray());
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return strOutput;
}
protected internal string Decrypt(string strInput, CipherMode cipherMode)
{
string strOutput = string.Empty;
if (!string.IsNullOrEmpty(strInput))
{
try
{
byte[] byteCipherText = Encoding.Default.GetBytes(strInput);
byte[] byteBuffer = new byte[strInput.Length];
using (RijndaelManaged rijManaged = new RijndaelManaged())
{
rijManaged.Mode = cipherMode;
rijManaged.BlockSize = 128;
rijManaged.KeySize = 128;
rijManaged.IV = GenerateIV();
rijManaged.Key = GenerateKey();
rijManaged.Padding = PaddingMode.Zeros;
ICryptoTransform icpoTransform = rijManaged.CreateDecryptor(rijManaged.Key, rijManaged.IV);
using (MemoryStream memStream = new MemoryStream(byteCipherText))
{
using (CryptoStream cpoStream = new CryptoStream(memStream, icpoTransform, CryptoStreamMode.Read))
{
cpoStream.Read(byteBuffer, 0, byteBuffer.Length);
}
strOutput = Encoding.Default.GetString(byteBuffer);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return strOutput;
}
}
}
You can use password from text box like key...
With this code you can encrypt/decrypt text, picture, word document, pdf....
public class Rijndael
{
private byte[] key;
private readonly byte[] vector = { 255, 64, 191, 111, 23, 3, 113, 119, 231, 121, 252, 112, 79, 32, 114, 156 };
ICryptoTransform EnkValue, DekValue;
public Rijndael(byte[] key)
{
this.key = key;
RijndaelManaged rm = new RijndaelManaged();
rm.Padding = PaddingMode.PKCS7;
EnkValue = rm.CreateEncryptor(key, vector);
DekValue = rm.CreateDecryptor(key, vector);
}
public byte[] Encrypt(byte[] byte)
{
byte[] enkByte= byte;
byte[] enkNewByte;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, EnkValue, CryptoStreamMode.Write))
{
cs.Write(enkByte, 0, enkByte.Length);
cs.FlushFinalBlock();
ms.Position = 0;
enkNewByte= new byte[ms.Length];
ms.Read(enkNewByte, 0, enkNewByte.Length);
}
}
return enkNeyByte;
}
public byte[] Dekrypt(byte[] enkByte)
{
byte[] dekByte;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, DekValue, CryptoStreamMode.Write))
{
cs.Write(enkByte, 0, enkByte.Length);
cs.FlushFinalBlock();
ms.Position = 0;
dekByte= new byte[ms.Length];
ms.Read(dekByte, 0, dekByte.Length);
}
}
return dekByte;
}
}
Convert password from text box to byte array...
private byte[] ConvertPasswordToByte(string password)
{
byte[] key = new byte[32];
for (int i = 0; i < passwprd.Length; i++)
{
key[i] = Convert.ToByte(passwprd[i]);
}
return key;
}
here is a neat and clean code to understand AES 256 algorithm implemented in C#
call Encrypt function as encryptedstring = cryptObj.Encrypt(username, "AGARAMUDHALA", "EZHUTHELLAM", "SHA1", 3, "#1B2c3D4e5F6g7H8", 256);
public class Crypt
{
public string Encrypt(string passtext, string passPhrase, string saltV, string hashstring, int Iterations, string initVect, int keysize)
{
string functionReturnValue = null;
// Convert strings into byte arrays.
// Let us assume that strings only contain ASCII codes.
// If strings include Unicode characters, use Unicode, UTF7, or UTF8
// encoding.
byte[] initVectorBytes = null;
initVectorBytes = Encoding.ASCII.GetBytes(initVect);
byte[] saltValueBytes = null;
saltValueBytes = Encoding.ASCII.GetBytes(saltV);
// Convert our plaintext into a byte array.
// Let us assume that plaintext contains UTF8-encoded characters.
byte[] plainTextBytes = null;
plainTextBytes = Encoding.UTF8.GetBytes(passtext);
// First, we must create a password, from which the key will be derived.
// This password will be generated from the specified passphrase and
// salt value. The password will be created using the specified hash
// algorithm. Password creation can be done in several iterations.
PasswordDeriveBytes password = default(PasswordDeriveBytes);
password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashstring, Iterations);
// Use the password to generate pseudo-random bytes for the encryption
// key. Specify the size of the key in bytes (instead of bits).
byte[] keyBytes = null;
keyBytes = password.GetBytes(keysize/8);
// Create uninitialized Rijndael encryption object.
RijndaelManaged symmetricKey = default(RijndaelManaged);
symmetricKey = new RijndaelManaged();
// It is reasonable to set encryption mode to Cipher Block Chaining
// (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC;
// Generate encryptor from the existing key bytes and initialization
// vector. Key size will be defined based on the number of the key
// bytes.
ICryptoTransform encryptor = default(ICryptoTransform);
encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
// Define memory stream which will be used to hold encrypted data.
MemoryStream memoryStream = default(MemoryStream);
memoryStream = new MemoryStream();
// Define cryptographic stream (always use Write mode for encryption).
CryptoStream cryptoStream = default(CryptoStream);
cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
// Start encrypting.
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
// Finish encrypting.
cryptoStream.FlushFinalBlock();
// Convert our encrypted data from a memory stream into a byte array.
byte[] cipherTextBytes = null;
cipherTextBytes = memoryStream.ToArray();
// Close both streams.
memoryStream.Close();
cryptoStream.Close();
// Convert encrypted data into a base64-encoded string.
string cipherText = null;
cipherText = Convert.ToBase64String(cipherTextBytes);
functionReturnValue = cipherText;
return functionReturnValue;
}
public string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)
{
string functionReturnValue = null;
// Convert strings defining encryption key characteristics into byte
// arrays. Let us assume that strings only contain ASCII codes.
// If strings include Unicode characters, use Unicode, UTF7, or UTF8
// encoding.
byte[] initVectorBytes = null;
initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] saltValueBytes = null;
saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
// Convert our ciphertext into a byte array.
byte[] cipherTextBytes = null;
cipherTextBytes = Convert.FromBase64String(cipherText);
// First, we must create a password, from which the key will be
// derived. This password will be generated from the specified
// passphrase and salt value. The password will be created using
// the specified hash algorithm. Password creation can be done in
// several iterations.
PasswordDeriveBytes password = default(PasswordDeriveBytes);
password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);
// Use the password to generate pseudo-random bytes for the encryption
// key. Specify the size of the key in bytes (instead of bits).
byte[] keyBytes = null;
keyBytes = password.GetBytes(keySize / 8);
// Create uninitialized Rijndael encryption object.
RijndaelManaged symmetricKey = default(RijndaelManaged);
symmetricKey = new RijndaelManaged();
// It is reasonable to set encryption mode to Cipher Block Chaining
// (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC;
// Generate decryptor from the existing key bytes and initialization
// vector. Key size will be defined based on the number of the key
// bytes.
ICryptoTransform decryptor = default(ICryptoTransform);
decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
// Define memory stream which will be used to hold encrypted data.
MemoryStream memoryStream = default(MemoryStream);
memoryStream = new MemoryStream(cipherTextBytes);
// Define memory stream which will be used to hold encrypted data.
CryptoStream cryptoStream = default(CryptoStream);
cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
// Since at this point we don't know what the size of decrypted data
// will be, allocate the buffer long enough to hold ciphertext;
// plaintext is never longer than ciphertext.
byte[] plainTextBytes = null;
plainTextBytes = new byte[cipherTextBytes.Length + 1];
// Start decrypting.
int decryptedByteCount = 0;
decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
// Close both streams.
memoryStream.Close();
cryptoStream.Close();
// Convert decrypted data into a string.
// Let us assume that the original plaintext string was UTF8-encoded.
string plainText = null;
plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
// Return decrypted string.
functionReturnValue = plainText;
return functionReturnValue;
}
}
I've already got it working between Java and Javascript, but the C# code does not work the same. That is, given a specific string to encrypt, the Java and Javascript code will generate the same result, but the C# code generates a different result.
Here is the Javascript code (which uses CryptoJS):
AesUtil.prototype.encrypt = function(salt, iv, passPhrase, plainText) {
var key = this.generateKey(salt, passPhrase);
var encrypted = CryptoJS.AES.encrypt(
plainText,
key,
{ iv: CryptoJS.enc.Hex.parse(iv) });
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
This code will encrypt "guest" as "WsH/YEUqqrWDxD15zxsUPg==".
Here is the Java code:
public String encrypt(String plainText, String salt, String passphrase, String iv) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{
byte[] plainTextbytes = plainText.getBytes(characterEncoding);
//byte[] keyBytes = getKeyBytes(salt);
SecretKey key = generateKey(salt, passphrase);
byte[] ivBytes = hex(iv);
return Base64.getEncoder().encodeToString(encrypt(plainTextbytes,key, ivBytes));//, Base64.DEFAULT);
}
private static SecretKey generateKey(String salt, String passphrase) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new javax.crypto.spec.PBEKeySpec(passphrase.toCharArray(), hex(salt), 10000, 128);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "Rijndael");
return key;
}
catch (NoSuchAlgorithmException e) {
throw fail(e);
}
catch (InvalidKeySpecException e) {
throw fail(e);
}
}
public static String hex(byte[] bytes) {
return Hex.encodeHexString(bytes);
}
This code also encrypts "guest" to "WsH/YEUqqrWDxD15zxsUPg==".
Here is my C# code:
public String Encrypt(String plainText, String passphrase, String salt, String iv, int iterations) {
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetSymmetricAlgorithm(passphrase, salt, iv, iterations)));
}
public byte[] Encrypt(byte[] plainBytes, SymmetricAlgorithm sa) {
return sa.CreateEncryptor().TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
public SymmetricAlgorithm GetSymmetricAlgorithm(String passphrase, String salt, String iv, int iterations) {
var saltBytes = new byte[16];
var ivBytes = new byte[16];
Rfc2898DeriveBytes rfcdb = new System.Security.Cryptography.Rfc2898DeriveBytes(passphrase, Encoding.UTF8.GetBytes(salt), iterations);
saltBytes = rfcdb.GetBytes(16);
var tempBytes = Encoding.UTF8.GetBytes(iv);
Array.Copy(tempBytes, ivBytes, Math.Min(ivBytes.Length, tempBytes.Length));
var rij = new RijndaelManaged(); //SymmetricAlgorithm.Create();
rij.Mode = CipherMode.CBC;
rij.Padding = PaddingMode.PKCS7;
rij.FeedbackSize = 128;
rij.KeySize = 128;
rij.BlockSize = 128;
rij.Key = saltBytes;
rij.IV = ivBytes;
return rij;
}
public byte[] Encrypt(byte[] plainBytes, SymmetricAlgorithm sa) {
return sa.CreateEncryptor().TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
This code encrypts "guest" to "F8t0D0vA2rxU3Ez1O5artA==". Notice that the resulting value is the same length, but it's not the same value, and is not decryptable by the Java code (which I haven't provided here -- I'm mainly concerned with getting all three encryptions to be the same).
Can anyone help? Thanks in advance.
You decode the IV from hex in JS and Java, but in C# you have var tempBytes = Encoding.UTF8.GetBytes(iv);. You would need to do the same Hex decoding in C#.