Reputation: 2145
I am busy creating a Javascript application which integrates with our client's existing C# services.
One of the requirements is to send AES encrypted data, which then is decrypted and used on the server.
However, I cannot send "valid" data, the server always responds with "Padding is invalid and cannot be removed."
Here are their C# Encrypt and Decrypt implementations (this cannot be changed, as they have various subsystems dependent on this:
public static string Encrypt(string input, string password)
{
byte[] utfData = Encoding.UTF8.GetBytes(input);
byte[] saltBytes = Encoding.UTF8.GetBytes(password);
string encryptedString = string.Empty;
using (var aes = new AesManaged())
{
var rfc = new Rfc2898DeriveBytes(password, saltBytes);
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
aes.KeySize = aes.LegalKeySizes[0].MaxSize;
aes.Key = rfc.GetBytes(aes.KeySize/8);
aes.IV = rfc.GetBytes(aes.BlockSize/8);
using (ICryptoTransform encryptTransform = aes.CreateEncryptor())
{
using (var encryptedStream = new MemoryStream())
{
using (var encryptor =
new CryptoStream(encryptedStream, encryptTransform, CryptoStreamMode.Write))
{
encryptor.Write(utfData, 0, utfData.Length);
encryptor.Flush();
encryptor.Close();
byte[] encryptBytes = encryptedStream.ToArray();
encryptedString = Convert.ToBase64String(encryptBytes);
}
}
}
}
return encryptedString;
}
public static string Decrypt(string input, string password)
{
byte[] encryptedBytes = Convert.FromBase64String(input);
byte[] saltBytes = Encoding.UTF8.GetBytes(password);
string decryptedString = string.Empty;
using (var aes = new AesManaged())
{
var rfc = new Rfc2898DeriveBytes(password, saltBytes);
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
aes.KeySize = aes.LegalKeySizes[0].MaxSize;
aes.Key = rfc.GetBytes(aes.KeySize/8);
aes.IV = rfc.GetBytes(aes.BlockSize/8);
using (ICryptoTransform decryptTransform = aes.CreateDecryptor())
{
using (var decryptedStream = new MemoryStream())
{
var decryptor =
new CryptoStream(decryptedStream, decryptTransform, CryptoStreamMode.Write);
decryptor.Write(encryptedBytes, 0, encryptedBytes.Length);
decryptor.Flush();
decryptor.Close();
byte[] decryptBytes = decryptedStream.ToArray();
decryptedString =
Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
}
}
}
return decryptedString;
}
I am using CryptoJS 3.1.2. eg
var encrypted = CryptoJS.AES.encrypt(input, password).toString();
how do I essentially write an equivalent to their "Encrypt()" using CryptoJS
Upvotes: 0
Views: 1655
Reputation: 94028
CryptoJS documentation is severely lacking in depth, so it is hard to know what to expect without trying. It is pretty clear though that using the password as salt is not a secure nor standard way to handle salt. So you will have to call the PBKDF2 function yourself, create a key and IV yourself. You also need to create the PBKDF2 in CryptoJS with SHA-1 instead of SHA-256. SHA-256 seems to be the - again undocumented - default in CryptoJS.
The only way to do this is to step through the code, and compare each (binary) value for both the PBKDF2 and AES functions. Please convert to hexadecimals to make a good comparison.
Upvotes: 4