PHP encryption not compatible with .NET/C# decryption (AES-256/CBC) - c#

when I try to encrypt using openssl_encrypt PHP I get square spaces at the end decrypted data which is shown in attached image
My API response is getting failure due to getting extra characters during decryption done by .NET side..
How can i resolve this issue please help
C#
public static string Decrypt(String encryptedText, String VendorKey, String Token)
{
var encryptedBytes = Convert.FromBase64String(encryptedText);
return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(VendorKey,Token)));
}
private static byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateDecryptor()
.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
}
public static RijndaelManaged GetRijndaelManaged(String VendorKey, String Token)
{
var keyBytes = new byte[32];
var ivBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(VendorKey + Token);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
var ivKeyBytes = Encoding.UTF8.GetBytes(VendorKey);
Array.Copy(ivKeyBytes, ivBytes, Math.Min(ivBytes.Length, ivKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.Zeros,
KeySize = 256,
BlockSize = 128,
Key = keyBytes,
IV = ivKeyBytes
};
}
public static string Encrypt(String plainText, String VendorKey, String Token)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(VendorKey, Token)));
}
private static byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
public static RijndaelManaged GetRijndaelManaged(String VendorKey, String Token)
{
var keyBytes = new byte[32];
var ivBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(VendorKey + Token);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
var ivKeyBytes = Encoding.UTF8.GetBytes(VendorKey);
Array.Copy(ivKeyBytes, ivBytes, Math.Min(ivBytes.Length, ivKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.Zeros,
KeySize = 256,
BlockSize = 128,
Key = keyBytes,
IV = ivKeyBytes
};
}
So can help me to resolve this issue

When using the sample data you provided, encryption with the .NET code:
string vendorKey = "0123456789012345";
string token = "012345";
string pt = #"{""prospectNo"":""SL1000000"",""paymentRequestDateFrom"":""2020-05-28"",""paymentRequestDateTo"":""2020-06-02"",""merchantTransactionId"":""7"",""callerReferenceNo"":""3""}";
string ct = Encrypt(pt, vendorKey, token);
Console.WriteLine(ct);
returns the following ciphertext:
g163a7jXmZKjH1J3RjC7xkPn5+PJWY6wTX9BgxiTY8hkYjsqImlCuvXOtZgUrrfLnwLy1QGUk6iylc/sInV/XJ9sypJ93tCvjRoj4s4RWGKTqUk3bY31JTM6QuYVclw4zNvyq2WUBCc+EMGGYtn5dBAvqiYdTqrJJTae67EZfgc4Fw5ormmf0rCYXQ2mn7mc1Jdg8v2r3LK9FYiwLEbhOA==
The PHP code below:
<?php
$cipher = "AES-256-CBC";
$array = json_encode(array(
"prospectNo"=> "SL1000000",
"paymentRequestDateFrom"=>"2020-05-28",
"paymentRequestDateTo"=>"2020-06-02",
"merchantTransactionId"=> "7",
"callerReferenceNo"=>"3"
)
);
$token = "012345";
$vendorKey = "0123456789012345";
$key = substr(str_pad($vendorKey . $token, 32, "\0"), 0, 32);
$iv = substr(str_pad($vendorKey, 16, "\0"), 0, 16);
$encrypted_data = openssl_encrypt(zeroPad($array, 16), $cipher, $key, OPENSSL_ZERO_PADDING, $iv);
print($encrypted_data . "\n");
function zeroPad($text, $bs) {
$pad = ($bs - strlen($text) % $bs) % $bs;
return ($pad > 0) ? $text . str_repeat("\0", $pad) : $text;
}
?>
gives the same ciphertext and is thus the PHP counterpart you are looking for, i.e. under the premise that the API can process the data encrypted by the .NET code, it must also process the data encrypted by the PHP code.
As expected, this ciphertext is decrypted into the correct plaintext by the .NET code. The hex encoded plaintext also reveals that the .NET code does not remove the padding bytes (note the 8 0x00 bytes at the end):
string vendorKey = "0123456789012345";
string token = "012345";
string ct = "g163a7jXmZKjH1J3RjC7xkPn5+PJWY6wTX9BgxiTY8hkYjsqImlCuvXOtZgUrrfLnwLy1QGUk6iylc/sInV/XJ9sypJ93tCvjRoj4s4RWGKTqUk3bY31JTM6QuYVclw4zNvyq2WUBCc+EMGGYtn5dBAvqiYdTqrJJTae67EZfgc4Fw5ormmf0rCYXQ2mn7mc1Jdg8v2r3LK9FYiwLEbhOA==";
string dt = Decrypt(ct, vendorKey, token);
Console.WriteLine("Plaintext: " + dt);
Console.WriteLine("Plaintext, hex: " + Convert.ToHexString(Encoding.UTF8.GetBytes(dt)));
with the output:
Plaintext: {"prospectNo":"SL1000000","paymentRequestDateFrom":"2020-05-28","paymentRequestDateTo":"2020-06-02","merchantTransactionId":"7","callerReferenceNo":"3"}
Plaintext, hex: 7B2270726F73706563744E6F223A22534C31303030303030222C227061796D656E74526571756573744461746546726F6D223A22323032302D30352D3238222C227061796D656E745265717565737444617465546F223A22323032302D30362D3032222C226D65726368616E745472616E73616374696F6E4964223A2237222C2263616C6C65725265666572656E63654E6F223A2233227D0000000000000000
The PHP code posted in this answer differs from your original PHP code essentially only in a more general derivation of $key and $iv (but this makes no difference for the vendorKey used here) and the padding. The original PHP code applied the default PKCS#7 padding used by openssl_encrypt(), while the current PHP code applies Zero padding.
Specifically, for the current plaintext, this means that the original PHP code padded with 0x0808080808080808, while the current PHP code pads with 0x0000000000000000. Since the .NET code does not remove the padding, the padding bytes are still present even when using the current PHP code (just with different values).

Related

How to properly call openssl_decrypt method if I have base64 string which contains from IV and encrypted data?

I have code in C# which encrypts and decrypts string:
private readonly UTF8Encoding _encoder;
private readonly ICryptoTransform _encryptor;
private readonly RijndaelManaged _rijndael;
public Crypter()
{
_rijndael = new RijndaelManaged { Key = { 1, 2, 3, 4, ..., 16 } };
_rijndael.GenerateIV();
_encryptor = _rijndael.CreateEncryptor();
_encoder = new UTF8Encoding();
}
public string Encrypt(string unencrypted)
=> Convert.ToBase64String(Encrypt(_encoder.GetBytes(unencrypted)));
private byte[] Encrypt(byte[] buffer)
{
byte[] inputBuffer = _encryptor.TransformFinalBlock(buffer, 0, buffer.Length);
return _rijndael.IV.Concat(inputBuffer).ToArray();
}
public string Decrypt(string encrypted)
=> _encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
private byte[] Decrypt(byte[] buffer)
{
byte[] iv = buffer.Take(16).ToArray();
using (ICryptoTransform decryptor = _rijndael.CreateDecryptor(_rijndael.Key, iv))
{
return decryptor.TransformFinalBlock(buffer, 16, buffer.Length - 16);
}
}
If you check Decrypt(byte[] buffer), I take first 16 bytes which is IV.
Now I similar want to implement in PHP (imagine, that I will encode on C# side and send it to server which runs on php, where I want to decrypt it back). As the param to my PHP decrypt function will be output of C# public string Encrypt(string unencrypted). I somehow need to get those 16 bytes to get IV and the rest part, which I respectively will pass as $data and $iv params to $decrypted_data = openssl_decrypt($data, $cipher, $encryption_key, 0, $iv); function
I have tried to use something like this (using unpack):
$stringValue = base64_decode($encrypted_data, true);
$integers = unpack("s*", $stringValue);
and then tried to take 16 first numbers and somehow convert them back with pack method. But probably I have lack of knowledge.
Could you please help me with this?
P.S. This one I have tried based on Ilya's answer and comments.
$cipher = "aes-256-cbc";
$encryption_key = hex2bin(env("ENCRYPTION_KEY"));
$base64decoded = base64_decode($encrypted_data, true);
$iv = substr($base64decoded, 0, 16);
$data = substr($base64decoded, 16, strlen($base64decoded) - 16);
$decrypted_data = openssl_decrypt($data, $cipher, $encryption_key, OPENSSL_RAW_DATA, $iv);
dd($decrypted_data);
also if I debug code and check which bytes are in $iv using this code:
$stringValue = base64_decode($iv, true);
$integers = unpack("C*", $encrypted_data);
and comparing with C# this byte array byte[] iv = buffer.Take(16).ToArray(); , they are equals, then I expect, that I am using wrongly openssl_decrypt method
In php any string is just a sequence of bytes, so you can work with it directly, e.g. access single byte by its index, or use substr to trim some amount of bytes. Example:
$str = 'some text or binary data received by http';
$first16Bytes = substr($str, 0, 16);
Firstly, I was having an issue how to correct retrieve 16 first bytes from string, because I thought I was doing it incorrectly. Thanks from #Ilia Yatsenko for his answer:
$first16Bytes = substr($str, 0, 16);
But then I have realised, that I am wrongly using openssl_decrypt() method. After having conversation in comments, particularly with #Topaco, we found what was the proble. Here is working code:
$cipher = "aes-256-cbc";
$encryption_key = hex2bin(env("ENCRYPTION_KEY"));
$base64decoded = base64_decode($encrypted_data, true);
$iv = substr($base64decoded, 0, 16);
$data = substr($base64decoded, 16, strlen($base64decoded) - 16);
$decrypted_data = openssl_decrypt($data, $cipher, $encryption_key,
OPENSSL_RAW_DATA, $iv);
dd($decrypted_data);

How to handle encrypt and decrypt file in ASP.NET core web API

What is the best way to implement encrypt and decrypt file content using asp.net core web API?
It should be compatible with the swagger also. I have tried this the same way as encrypt a string, but there is a limitation of size length or incomplete file sent over API.
I require to encrypt at the client end before API call via swagger or postman and be decrypt at service end.
File content encrypts at the client end then only data at transmission will safe.
I have tried below
public static string encrypt(string PlainText, byte[] key, byte[] iv)
{
string sR = string.Empty;
byte[] plainBytes = Encoding.UTF8.GetBytes(PlainText);
GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());
AeadParameters parameters =
new AeadParameters(new KeyParameter(key), 128, iv, null);
cipher.Init(true, parameters);
byte[] encryptedBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
Int32 retLen = cipher.ProcessBytes
(plainBytes, 0, plainBytes.Length, encryptedBytes, 0);
cipher.DoFinal(encryptedBytes, retLen);
sR = Convert.ToBase64String(encryptedBytes, Base64FormattingOptions.None);
return sR;
}
You can take a look at this link: https://github.com/2Toad/Rijndael256/issues/13#issuecomment-637724412
It uses the Rijndael/AES cypher to encrypt the data you put in.
In the Github issue you will find the following code:
public static class CipherHelper
{
// This constant is used to determine the keysize of the encryption algorithm in bits.
// We divide this by 8 within the code below to get the equivalent number of bytes.
private const int Keysize = 256;
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
public static string Encrypt(string plainText, string passPhrase)
{
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
// so that the same Salt and IV values can be used when decrypting.
var saltStringBytes = Generate256BitsOfRandomEntropy();
var ivStringBytes = Generate256BitsOfRandomEntropy();
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
cipher.Init(true, keyParamWithIV);
var comparisonBytes = new byte[cipher.GetOutputSize(plainTextBytes.Length)];
var length = cipher.ProcessBytes(plainTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
// return Convert.ToBase64String(comparisonBytes);
return Convert.ToBase64String(saltStringBytes.Concat(ivStringBytes).Concat(comparisonBytes).ToArray());
}
}
public static string Decrypt(string cipherText, string passPhrase)
{
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
cipher.Init(false, keyParamWithIV);
var comparisonBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
var length = cipher.ProcessBytes(cipherTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
//return Convert.ToBase64String(saltStringBytes.Concat(ivStringBytes).Concat(comparisonBytes).ToArray());
var nullIndex = comparisonBytes.Length - 1;
while (comparisonBytes[nullIndex] == (byte)0)
nullIndex--;
comparisonBytes = comparisonBytes.Take(nullIndex + 1).ToArray();
var result = Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length);
return result;
}
}
private static byte[] Generate256BitsOfRandomEntropy()
{
var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
using (var rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with cryptographically secure random bytes.
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
}
To make this code work, you will need to install the BouncyCastle.NetCore NuGet package.
This code helps you to encrypt and decrypt a string by using a password.
In your case, if you somehow now the password at both sides of the request (send-side and receive-side) than this should be able to work.

Aes Encrypt and Decrypt null adds bytes

Hi there i'm using this encryption method to encrypt my json value in .net side
public static string Encrypt256(string text)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = Encoding.UTF8.GetBytes(AesIV256);
aes.Key = Encoding.UTF8.GetBytes(AesKey256);
aes.Mode = CipherMode.CBC;
byte[] src = Encoding.Unicode.GetBytes(text);
using (ICryptoTransform encrypt = aes.CreateEncryptor())
{
byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
Debug.WriteLine(Convert.ToBase64String(dest));
return Convert.ToBase64String(dest);
}
}
And im trying to decrypt it in Node Js side
var crypto = require('crypto'),
algorithm = process.env.tombalaCryptoAlgorithm,
password = process.env.tombalaHmacPass,
iv = '!QAZ2WSX#EDC4RFV'
function encrypt(text) {
var cipher = crypto.createCipheriv(algorithm, password, iv)
var encrypted = cipher.update(text, 'utf8', 'base64')
encrypted += cipher.final('base64');
return encrypted;
You are converting your text to be encrypted to Unicode which means UTF-16.
In UTF-16 every character consists of two bytes. If the second byte is not used it is null as you have observed.
I assume you want UTF-8 encoding. Therefore replace the line
byte[] src = Encoding.Unicode.GetBytes(text);
with
byte[] src = Encoding.UTF8.GetBytes(text);

Invalid padding error when using AesCryptoServiceProvider in C#

I've written a simple encryp/decrypt method in c# which uses the AES alg. When I try to encrypt and then decrypt a string with certain lengths like 4 or 7 characters, it works fine, with other lengths however It says that the padding is invalid and cannot be removed.
public static string Decrypt(string text)
{
Aes a = System.Security.Cryptography.AesCryptoServiceProvider.Create();
a.Padding = PaddingMode.PKCS7;
a.Key = Convert.FromBase64String("UDlArN63HCk15fHBski/zvaWiMZJi+jR1BADvVgenCU=");
a.IV = Convert.FromBase64String("xZG/eLY8eq0mQhUXvKbUDQ==");
var dc = a.CreateDecryptor();
byte[] encryptedBytes = Encoding.Unicode.GetBytes(text);
byte[] decryptedBytes = dc.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return Encoding.Unicode.GetString(decryptedBytes);
}
public static string Encrypt(string text)
{
Aes a = System.Security.Cryptography.AesCryptoServiceProvider.Create();
a.Padding = PaddingMode.PKCS7;
a.Key = Convert.FromBase64String("UDlArN63HCk15fHBski/zvaWiMZJi+jR1BADvVgenCU=");
a.IV = Convert.FromBase64String("xZG/eLY8eq0mQhUXvKbUDQ==");
var dc = a.CreateEncryptor();
byte[] decryptedBytes = Encoding.Unicode.GetBytes(text);
byte[] encryptedBytes = dc.TransformFinalBlock(decryptedBytes, 0, decryptedBytes.Length);
return Encoding.Unicode.GetString(encryptedBytes);
}
Ciphertexts are binary data which might contain bytes that are not printable. If try to encode the byte array as a Unicode string, you will lose some bytes. It will be impossible to recover them during decryption.
If you actually want to handle the ciphertext as a string, you need to convert it into a textual representation like Base 64 or Hex.
// encryption
return Convert.ToBase64String(decryptedBytes);
// decryption
byte[] decryptedBytes = Convert.FromBase64String(text);

C# / Java | AES256 encrypt/decrypt

I want to encrypt all the data I send through the Java/C# sockets (Java server, C# client).
I would like to use AES256, but I can't get the Java and C# to generate the same encrypted code. Can anyone give me two examples, 1 in Java and 1 in C# that generate the same results and decrypts the results properly?
What I tried so far:
public Encrypt(AOBCore instance){
try {
String message="This is just an example";
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(256); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey(); //Cantget 'test' in here...
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted =
cipher.doFinal(message.getBytes());
System.out.println("encrypted string: " + asHex(encrypted));
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original =
cipher.doFinal(encrypted);
String originalString = new String(original);
System.out.println("Original string: " +
originalString + " " + asHex(original));
} catch (Exception e) {
instance.logMessage(e.getMessage());
}
}
public static String asHex (byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
}
static void Main(string[] args)
{
while (true)
{
var plain = Console.ReadLine();
var key = GenerateKey(256);
var encoded = Encrypt(plain, key, 256);
Console.WriteLine("Encoded: " + encoded);
Console.WriteLine(Decrypt(encoded, key, 256));
}
}
private static string GenerateKey(int keySize)
{
return "test";
}
private static string Encrypt(string plainStr, string completeEncodedKey, int keySize)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.KeySize = keySize;
aesEncryption.BlockSize = 256;
aesEncryption.Mode = CipherMode.CBC;
aesEncryption.Padding = PaddingMode.PKCS7;
aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr);
ICryptoTransform crypto = aesEncryption.CreateEncryptor();
// The result of the encryption and decryption
byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
return Convert.ToBase64String(cipherText);
}
private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.KeySize = keySize;
aesEncryption.BlockSize = 128;
aesEncryption.Mode = CipherMode.CBC;
aesEncryption.Padding = PaddingMode.PKCS7;
aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
}
The problem is that you aren't specifying the ciphermode or the padding in the Java code. This will use the algorithm defaults, which is never something you want to do when interoperability with other libraries is required. Initialize your Cipher like this:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
PKCS5 in Java should be compatible with PKCS7 in .Net according to this answer. Since you are wisely using CBC you are going to need to modify the code to use the same initialization vector for both encryption and decryption. You should NOT use the secret key for that. The IV should be randomly generated. You can use the IV that the Java Cipher generated for encryption by calling cipher.getIV().
Also, take care to be consistent with character encodings as has been mentioned in the comments.

Categories