'Encrypt in java and Decrypt in C# For AES 256 bit
1.I have java function which encrypt xml file and return encrypted String.
/// Java Class
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Crypt {
public static String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
public static byte[] key_Array = Base64.decodeBase64(key);
public static String encrypt(String strToEncrypt)
{
try
{
//Cipher _Cipher = Cipher.getInstance("AES");
//Cipher _Cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
//Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
Key SecretKey = new SecretKeySpec(key_Array, "AES");
Cipher _Cipher = Cipher.getInstance("AES");
_Cipher.init(Cipher.ENCRYPT_MODE, SecretKey);
return Base64.encodeBase64String(_Cipher.doFinal(strToEncrypt.getBytes()));
}
catch (Exception e)
{
System.out.println("[Exception]:"+e.getMessage());
}
return null;
}
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("xml file string ...");
String EncryptedString = encrypt(sb.toString());
System.out.println("[EncryptedString]:"+EncryptedString);
}
}
2.I have c# function which decrypt the message which is encrypted by java function.
/// C# Function
private static string Decrypt(string encryptedText)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.BlockSize = 256;
//aesEncryption.KeySize = 256;
//aesEncryption.Mode = CipherMode.CBC;
//aesEncryption.Padding = PaddingMode.PKCS7;
string keyStr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
//string ivStr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
byte[] keyArr = Convert.FromBase64String(keyStr);
//byte[] ivArr = Convert.FromBase64String(ivStr);
aesEncryption.Key = keyArr;
//aesEncryption.IV = ivArr;
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
byte[] decryptedData = decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); /// CryptographicException: Length of the data to decrypt is invalid.
return ASCIIEncoding.UTF8.GetString(decryptedData);
}
Java encrypt function is work well. But the problem is C# function,
when I decrypt I get below error message
CryptographicException: Length of the data to decrypt is invalid.
I searched solutions by using below ref
- AES Encryption in Java and Decryption in C#
- C# / Java | AES256 encrypt/decrypt
- Encyption/Decryption in C# and Java
but I still face the same error.Could anyone give me suggestion please.
Updated
I Just change my C# crypto function. Below is my change lists
- Block Size to 128
- Key Size to 256
- IV Size to 16
- Key Size to 32
/// Updated decrypt function
private static string Decrypt(string encryptedText)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.BlockSize = 128;
aesEncryption.KeySize = 256;
//aesEncryption.Mode = CipherMode.CBC;
aesEncryption.Padding = PaddingMode.None;
string keyStr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string ivStr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
byte[] ivArr = Convert.FromBase64String(ivStr);
byte[] IVkey16BytesValue = new byte[16];
Array.Copy(ivArr, IVkey16BytesValue, 16);
byte[] keyArr = Convert.FromBase64String(keyStr);
byte[] KeyArr32BytesValue = new byte[32];
Array.Copy(keyArr, KeyArr32BytesValue, 32);
aesEncryption.IV = IVkey16BytesValue;
aesEncryption.Key = KeyArr32BytesValue;
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
byte[] decryptedData = decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return ASCIIEncoding.UTF8.GetString(decryptedData);
}
In this time, no error occur. But I get decrypted message which i cannot read.
g:�\0�\td��Y\\符O����\rL��W�wHm�>f�\au����%��0��\ ..........
Please let me get your suggestion again.
Solution 1:[1]
After I got very helpful suggestions from @deathismyfriend and other, I found out what I am missing in my C# Decrypt function.So I change my function as below.
/// C# Error Fixed Version - CipherMode.ECB
public static string keyStr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static string Encrypt(string PlainText)
{
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
/// In Java, Same with below code
/// Cipher _Cipher = Cipher.getInstance("AES"); // Java Code
aes.Mode = CipherMode.ECB;
byte[] keyArr = Convert.FromBase64String(keyStr);
byte[] KeyArrBytes32Value = new byte[32];
Array.Copy(keyArr, KeyArrBytes32Value, 32);
aes.Key = KeyArrBytes32Value;
ICryptoTransform encrypto = aes.CreateEncryptor();
byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(PlainText);
byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);
return Convert.ToBase64String(CipherText);
}
private static string Decrypt(string CipherText)
{
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
/// In Java, Same with below code
/// Cipher _Cipher = Cipher.getInstance("AES"); // Java Code
aes.Mode = CipherMode.ECB;
byte[] keyArr = Convert.FromBase64String(keyStr);
byte[] KeyArrBytes32Value = new byte[32];
Array.Copy(keyArr, KeyArrBytes32Value, 32);
aes.Key = KeyArrBytes32Value;
ICryptoTransform decrypto = aes.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(CipherText.ToCharArray(), 0, CipherText.Length);
byte[] decryptedData = decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return ASCIIEncoding.UTF8.GetString(decryptedData);
}
By using upper c# function , now I can decrypt and read cipher text.
Below is what I found out after I getting error again and again.
CryptographicException: Padding is invalid and cannot be removed.
Solution:
_RijndaelManaged.Padding = CipherMode.xxx; ///should toggle here
_RijndaelManaged.Padding = PaddingMode.xxx; ///should toggle here
CryptographicException: Length of the data to decrypt is invalid.
CryptographicException: Specified initialization vector (IV) does not match the block size for this algorithm.
Solution
1. _RijndaelManaged.BlockSize = 128; /// Must be
2. _RijndaelManaged.KeySize = 256; /// Must be
3. _RijndaelManaged.Key = Byte Array Size must be 32 in length ( more detail 32*8 = 256 KeySize )
4. _RijndaelManaged.IV = Byte Array Size must be 16 in length ( more detail 16*8 = 128 BlockSize)
But when it come to security reason, I think I should not use ECB mode.
According to
So I Modify it again in Java and C#.
// Java code - Cipher mode CBC version.
// CBC version need Initialization vector IV.
// Reference from https://stackoverflow.com/questions/6669181/why-does-my-aes-encryption-throws-an-invalidkeyexception/6669812#6669812
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class CryptoSecurity {
public static String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
public static byte[] key_Array = Base64.decodeBase64(key);
public static String encrypt(String strToEncrypt)
{
try
{
//Cipher _Cipher = Cipher.getInstance("AES");
//Cipher _Cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
// Initialization vector.
// It could be any value or generated using a random number generator.
byte[] iv = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 7, 7, 7 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
Key SecretKey = new SecretKeySpec(key_Array, "AES");
_Cipher.init(Cipher.ENCRYPT_MODE, SecretKey, ivspec);
return Base64.encodeBase64String(_Cipher.doFinal(strToEncrypt.getBytes()));
}
catch (Exception e)
{
System.out.println("[Exception]:"+e.getMessage());
}
return null;
}
public static String decrypt(String EncryptedMessage)
{
try
{
//Cipher _Cipher = Cipher.getInstance("AES");
//Cipher _Cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
// Initialization vector.
// It could be any value or generated using a random number generator.
byte[] iv = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 7, 7, 7 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
Key SecretKey = new SecretKeySpec(key_Array, "AES");
_Cipher.init(Cipher.DECRYPT_MODE, SecretKey, ivspec);
byte DecodedMessage[] = Base64.decodeBase64(EncryptedMessage);
return new String(_Cipher.doFinal(DecodedMessage));
}
catch (Exception e)
{
System.out.println("[Exception]:"+e.getMessage());
}
return null;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
sb.append("xml file string ...");
String outputOfEncrypt = encrypt(sb.toString());
System.out.println("[CryptoSecurity.outputOfEncrypt]:"+outputOfEncrypt);
String outputOfDecrypt = decrypt(outputOfEncrypt);
//String outputOfDecrypt = decrypt(sb.toString());
System.out.println("[CryptoSecurity.outputOfDecrypt]:"+outputOfDecrypt);
}
}
In C#, I modify it like below.
// C# Code, CipherMode.CBC
// CBC version need Initialization vector IV.
public static string keyStr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static string Encrypt(string PlainText)
{
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
// It is equal in java
/// Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
byte[] keyArr = Convert.FromBase64String(keyStr);
byte[] KeyArrBytes32Value = new byte[32];
Array.Copy(keyArr, KeyArrBytes32Value, 32);
// Initialization vector.
// It could be any value or generated using a random number generator.
byte[] ivArr = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 7, 7, 7 };
byte[] IVBytes16Value = new byte[16];
Array.Copy(ivArr, IVBytes16Value, 16);
aes.Key = KeyArrBytes32Value;
aes.IV = IVBytes16Value;
ICryptoTransform encrypto = aes.CreateEncryptor();
byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(PlainText);
byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);
return Convert.ToBase64String(CipherText);
}
private static string Decrypt(string CipherText)
{
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
byte[] keyArr = Convert.FromBase64String(keyStr);
byte[] KeyArrBytes32Value = new byte[32];
Array.Copy(keyArr, KeyArrBytes32Value, 32);
// Initialization vector.
// It could be any value or generated using a random number generator.
byte[] ivArr = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 7, 7, 7 };
byte[] IVBytes16Value = new byte[16];
Array.Copy(ivArr, IVBytes16Value, 16);
aes.Key = KeyArrBytes32Value;
aes.IV = IVBytes16Value;
ICryptoTransform decrypto = aes.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(CipherText.ToCharArray(), 0, CipherText.Length);
byte[] decryptedData = decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return ASCIIEncoding.UTF8.GetString(decryptedData);
}
Now it all work.
For more detail about AES, click this link which I was given by @deathismyfriend.
It is also very useful.
Solution 2:[2]
On one of my recent projects I was tasked with building up a url with an encrypted portion to pass to another website. They ran java on their server, whereas we developed in c#.
I know this isn't an exact match to what you were tasked to create, but hopefully this can help out others that are trying to find answers :)
I received the following from their developers to build our encryption off from

To accomplish this in c# I did the following:
public String Encrypt(String plainText, String key)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(key)));
}
private RijndaelManaged GetRijndaelManaged(String secretKey)
{
var keyBytes = new byte[16];
var secretKeyBytes = Encoding.ASCII.GetBytes(secretKey);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7,
KeySize = 128,
BlockSize = 128,
Key = keyBytes,
IV = keyBytes
};
}
private byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
Solution 3:[3]
I had a problem with this algorithm (in Java only) and I did a litle changes.
// Java code - Cipher mode CBC version.
// CBC version need Initialization vector IV.
// Reference from https://stackoverflow.com/questions/6669181/why-does-my-aes-encryption-throws-an-invalidkeyexception/6669812#6669812
public static String key = "FFClY170hLrhsDnKUEhJ4FhVOnrpNNFFClY170hLrhsDnKUE";
public static byte[] key_Array = Base64.decodeBase64(key);
public static String encrypt(String strToEncrypt) {
try {
//Cipher _Cipher = Cipher.getInstance("AES");
//Cipher _Cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
// Initialization vector.
// It could be any value or generated using a random number generator.
byte[] iv = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 7, 7, 7};
IvParameterSpec ivspec = new IvParameterSpec(iv);
key_Array = Arrays.copyOf(key_Array, 32);
Key SecretKey = new SecretKeySpec(key_Array, "AES");
_Cipher.init(Cipher.ENCRYPT_MODE, SecretKey, ivspec);
return Base64.encodeBase64String(_Cipher.doFinal(strToEncrypt.getBytes()));
} catch (Exception e) {
System.out.println("[Exception]:" + e.getMessage());
}
return null;
}
public static String decrypt(String EncryptedMessage) {
try {
//Cipher _Cipher = Cipher.getInstance("AES");
//Cipher _Cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
Cipher _Cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
// Initialization vector.
// It could be any value or generated using a random number generator.
byte[] iv = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 7, 7, 7};
IvParameterSpec ivspec = new IvParameterSpec(iv);
key_Array = Arrays.copyOf(key_Array, 32);
Key SecretKey = new SecretKeySpec(key_Array, "AES");
_Cipher.init(Cipher.DECRYPT_MODE, SecretKey, ivspec);
byte DecodedMessage[] = Base64.decodeBase64(EncryptedMessage);
return new String(_Cipher.doFinal(DecodedMessage));
} catch (Exception e) {
System.out.println("[Exception]:" + e.getMessage());
}
return null;
}
Solution 4:[4]
public static void setSecretkeys(string keyvalue) { byte[] bytes = Encoding.Default.GetBytes(keyvalue); keyvalue = Encoding.UTF8.GetString(bytes);
byte[] result;
SHA256 shaM = new SHA256Managed();
result = shaM.ComputeHash(bytes);
Array.Copy(result, keybytes, 16);
//Console.WriteLine("This is the encryption key " + Encoding.UTF8.GetString(keybytes));
}
public string Decryptxx(string text, string keyValue)
{
setSecretkeys(keyValue);
byte[] src = Convert.FromBase64String(text);
RijndaelManaged aes = new RijndaelManaged();
byte[] key = keybytes;
aes.KeySize = 128;
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.ECB;
using (ICryptoTransform decrypt = aes.CreateDecryptor(key, null))
{
byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
decrypt.Dispose();
return Encoding.UTF8.GetString(dest);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Community |
| Solution 2 | A Kimmel |
| Solution 3 | Allan Jacques Neves de Oliveir |
| Solution 4 |
