I have the following encrypt/decrypt methods on JAVA
private static final String ALGORITHM = "AES";
protected static String encrypt(String valueToEnc, byte[] keyValue) throws Exception {
Key key = generateKey(keyValue);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = new BASE64Encoder().encode(encValue);
return encryptedValue;
}
protected static String decrypt(String encryptedValue, byte[] keyValue) throws Exception {
try
{
Key key = generateKey(keyValue);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
catch(Exception ex)
{
return "";
}
}
private static Key generateKey(byte[] keyValue) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
return key;
}
What would be the equivalent decryption for (C#).NET?. I have tested some Cipher examples that I have found, but none of them return the same as the Java Version.
Thanks.
Try this:
using System;
using System.IO;
using System.Security.Cryptography;
namespace Aes_Example
{
class AesExample
{
public static void Main()
{
try
{
string original = "Here is some data to encrypt!";
// Create a new instance of the AesCryptoServiceProvider
// class. This generates a new key and initialization
// vector (IV).
using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider())
{
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.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_Aes(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 AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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_Aes(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 AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.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;
}
}
}
source: http://msdn.microsoft.com/en-us/library/system.security.cryptography.aescryptoserviceprovider(v=vs.110).aspx
Related
Decryption logic is missing something can you please assist.
Output is not completely decrypted.
Java Encryption Logic:
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException {
try {
String in ="This is a text message";
byte[] input = in.toString().getBytes("utf-8");
String ENCRYPTION_KEY = "RW50ZXIgS2V5IEhlcmU=";
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] thedigest = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
// SecretKeySpec skc = new SecretKeySpec(thedigest, "AES/ECB/PKCS5Padding");
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
// String query = Base64.encodeToString(cipherText, Base64.DEFAULT);
String query = new String(java.util.Base64.getEncoder().encode(cipherText));
System.out.println("query " + query);
// String query = new String(encode(cipherText), StandardCharsets.ISO_8859_1);
} catch(UnsupportedEncodingException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
}
Nodejs Decryption Logic:
let crypto = require('crypto');
var decipher = crypto.createDecipher('aes-256-ecb', "RW50ZXIgS2V5IEhlcmU=");
decipher.setAutoPadding(false);
console.log(decipher.update("EncyptedText", 'base64', 'utf8') + decipher.final('utf8'));
I am trying to save encrypted data to a Text file and then open and decrypt it. When I try to Decrypt it I receive the error "Padding is Invalid and Cannot Be Removed." I am using example code directly from Microsoft for encryption and decryption.
Here is MY code to encrypt and save file:
string json = JsonConvert.SerializeObject(credentials);
using (AesManaged myAes = new AesManaged())
{
byte[] encrypted = ControlHelperscs.EncryptStringToBytes_Aes(json, myAes.Key, myAes.IV);
File.WriteAllBytes(subPath, encrypted);
}
Here is my code to Retrieve and Decrypt file:
using (AesManaged myAes = new AesManaged())
{
byte[] file = File.ReadAllBytes(subPath);
string decrypt = ControlHelperscs.DecryptStringFromBytes_Aes(file, myAes.Key, myAes.IV);
credentials = JsonConvert.DeserializeObject<LoginModel>(decrypt);
}
Here are Encrypt and Decrypt methods:
public static byte[] EncryptStringToBytes_Aes(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 AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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;
}
public static string DecryptStringFromBytes_Aes(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 AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.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'm sorry I deleted my comment (it was wrong in that context), but I reworked your example to have a little less boilerplate and be able to encrypt and decrypt properly. The problem is that you're generating a new and different Key/IV pair to decrypt from the one you used to encrypt. Of course it won't be able to decrypt. So, here is the part to make it work:
byte[] key;
byte[] iv;
string json = JsonConvert.SerializeObject(credentials);
using (AesManaged myAes = new AesManaged())
{
key = myAes.Key;
iv = myAes.IV;
byte[] encrypted = ControlHelperscs.EncryptStringToBytes_Aes(json, key, iv);
File.WriteAllBytes(subPath, encrypted);
}
byte[] file = File.ReadAllBytes(subPath);
string decrypt = ControlHelperscs.DecryptStringFromBytes_Aes(file, key, iv);
credentials = JsonConvert.DeserializeObject<LoginModel>(decrypt);
and here are the slightly reworked heavy-lifting methods to be a bit more compact:
public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] iv)
{
// Check arguments.
if (plainText is null)
{
throw new ArgumentNullException(nameof(plainText));
}
if (plainText.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(plainText), plainText, "length cannot be zero");
}
if (key is null)
{
throw new ArgumentNullException(nameof(key));
}
if (key.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(key), key, "length cannot be zero");
}
if (iv is null)
{
throw new ArgumentNullException(nameof(iv));
}
if (iv.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(iv), iv, "length cannot be zero");
}
// Create an AesManaged object
// with the specified key and IV.
// Create an encryptor to perform the stream transform.
// Create the streams used for encryption.
using (SymmetricAlgorithm aesAlg = new AesManaged { Key = key, IV = iv })
using (ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV))
using (MemoryStream msEncrypt = new MemoryStream())
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (TextWriter swEncrypt = new StreamWriter(csEncrypt))
{
// Write all data to the stream.
swEncrypt.Write(plainText);
swEncrypt.Flush();
csEncrypt.FlushFinalBlock();
// Return the encrypted bytes from the memory stream.
return msEncrypt.ToArray();
}
}
public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] key, byte[] iv)
{
// Check arguments.
if (cipherText is null)
{
throw new ArgumentNullException(nameof(cipherText));
}
if (cipherText.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(cipherText), cipherText, "length cannot be zero");
}
if (key is null)
{
throw new ArgumentNullException(nameof(key));
}
if (key.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(key), key, "length cannot be zero");
}
if (iv is null)
{
throw new ArgumentNullException(nameof(iv));
}
if (iv.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(iv), iv, "length cannot be zero");
}
// Create an AesManaged object
// with the specified key and IV.
// Create a decryptor to perform the stream transform.
// Create the streams used for decryption.
using (SymmetricAlgorithm aesAlg = new AesManaged { Key = key, IV = iv })
using (ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
using (Stream msDecrypt = new MemoryStream(cipherText))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (TextReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
return srDecrypt.ReadToEnd();
}
}
I want to decrypt AES 128 in Universal app (win 10), but we do not have AesManaged because this lib doesn't exist in System.Security.Cryptography.
So, how can I decrypt my string in UWA c#?
I use this code in windows phone 8 :
public static string DecryptString(string cipherText)
{
const string password = "myPass";
string plaintext = null;
try
{
if (!string.IsNullOrEmpty(cipherText))
{
if (cipherText != "")
{
var key = new byte[KeySize];
var passwordbytes = Encoding.UTF8.GetBytes(password);
for (var i = 0; i < KeySize; i++)
{
if (i >= passwordbytes.Length)
{
key[i] = 0;
break;
}
key[i] = passwordbytes[i];
}
var cipherTextBytes = Convert.FromBase64String(cipherText.Replace("-", "+").Replace("_", "/"));
// Declare the string used to hold
// the decrypted text.
BCEngine
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (var aesAlg = new AesManaged())
{
//aesAlg.Mode = CipherMode.CBC;
aesAlg.KeySize = KeySize * 8;
// Create a decrytor to perform the stream transform.
var decryptor = aesAlg.CreateDecryptor(key, Iv);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherTextBytes))
{
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();
}
}
}
}
}
}
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
}
return plaintext;
}
I have to use encryption / decryption mechanism for a j2me application and lots of searching I found that Bouncy Castle is most suitable for j2me apps.
Below are the steps that I follow to perform encryption:
Get a string needed to create a hash key using sha256 algorithm;
With that hash key perform AES-128 encryption for a plain text.
Below is the sample code. It is using key and IV (Initialization Vector) for encryption key generation. Is it same as sha256 hashing?
static String strEnc = "String for encryption";
final static String strPassword = "2345678978787878"; // AES 128 -
String encrypted;
public static String strEncResult;
public static String strDcrResult;
public static String keyStr;
String dcrtpt;
String enc1;
//Key key;
/*public static byte[] getSHA256(String key) {
SHA256Digest digester = new SHA256Digest();
byte[] retValue = new byte[digester.getDigestSize()];
digester.update(key.getBytes(), 0, key.length());
digester.doFinal(retValue, 0);
System.out.println("retValue === "+retValue);
return retValue;
}*/
public static byte[] cipherData(PaddedBufferedBlockCipher cipher,
byte[] data) throws Exception {
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
public static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv)
throws Exception {
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key),
iv);
aes.init(false, ivAndKey);
return cipherData(aes, cipher);
}
public static byte[] encrypt(byte[] plain, byte[] key, byte[] iv)
throws Exception {
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key),
iv);
aes.init(true, ivAndKey);
return cipherData(aes, plain);
}
public static String encryptMe(String plain){
byte[] plainStr = plain.getBytes();
byte[] keyStr = strPassword.getBytes();//getSHA256(strPassword);
byte[] ivStr = strPassword.getBytes();//getSHA256(strPassword);
try {
byte[] encBytes = encrypt(plainStr, keyStr,
ivStr);
byte[] encbase = Base64.encode(encBytes);
strEncResult = new String(encbase, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return strEncResult;
}
public static String decryptMe(String encrtptedStr){
try {
byte[] dcrByte = Base64.decode(encrtptedStr.getBytes());
byte[] dec = decrypt(dcrByte, strPassword.getBytes()/*getSHA256(strPassword)*/,
strPassword.getBytes()/*getSHA256(strPassword)*/);
strDcrResult = new String(dec, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return strDcrResult;
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
byte[] enc;
try {
enc = encrypt(strEnc.getBytes(), /*getSHA256(strPassword)*/strPassword.getBytes(),
/*getSHA256(strPassword)*/strPassword.getBytes());
byte[] encbase = Base64.encode(enc);
encrypted = new String(encbase, "UTF-8");
enc1= encryptMe ("String for encryption");
System.out.println("Encrypted is:" + encbase + "/// "+enc1);
} catch (Exception e) {
e.printStackTrace();
}
byte[] decbase = Base64.decode(encrypted.getBytes());
byte[] dec;
try {
dec = decrypt(decbase, /*getSHA256(strPassword)*/strPassword.getBytes(),
/*getSHA256(strPassword)*/strPassword.getBytes());
dcrtpt = decryptMe(enc1);
System.out.println("Decrypted file is:" + new String(dec, "UTF-8")+"///"+dcrtpt);
} catch (Exception e) {
e.printStackTrace();
}
}
i got it worked!!. i have used sha256 for secret key generation and took first 16 digit for AES 128 encryption. i am getting correct encrypted and decrypted data when it is 16 or below 16 string. if it is above 16 char string i am getting 16 char with some unwanted characters. (Eg: abcdefghijklmnop5#�D�!�&M�\~C��) can anybody help me to sort this issue. please see below for code
public static String getSHA256(String key) {
SHA256Digest digester = new SHA256Digest();
byte[] retValue = new byte[digester.getDigestSize()];
digester.update(key.getBytes(), 0, key.length());
digester.doFinal(retValue,0);
byteToStr = new String(Hex.encode(retValue));
System.out.println("byteToStr === " + byteToStr);
byteToStr = byteToStr.substring(0, 16);
System.out.println("byteToStr after subString === " + byteToStr);
return byteToStr;
}
public static byte[] cipherData(BufferedBlockCipher cipher, byte[] data)
throws Exception {
int minSize = cipher.getOutputSize(data.length);
System.out.println("min Size = "+minSize);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
System.out.println("length1 = "+length1 +"/ length2 = "+length2);
int actualLength = length1 + length2;
System.out.println("actualLength = "+actualLength);
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
public static byte[] decrypt(byte[] cipher, byte[] key/* , byte[] iv */)
throws Exception {
/*
* PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher( new
* CBCBlockCipher(new AESEngine())); CipherParameters ivAndKey = new
* ParametersWithIV(new KeyParameter(key), iv); aes.init(false,
* ivAndKey); return cipherData(aes, cipher);
*/
BufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
KeyParameter secretKey = new KeyParameter(key);
aes.init(false, secretKey);
return cipherData(aes, cipher);
}
public static byte[] encrypt(byte[] plain, byte[] key/* , byte[] iv */)
throws Exception {
/*
* PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher( new
* CBCBlockCipher(new AESEngine())); CipherParameters ivAndKey = new
* ParametersWithIV(new KeyParameter(key), iv);
*/
BufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESEngine()));
KeyParameter secretKey = new KeyParameter(key);
aes.init(true, secretKey);
return cipherData(aes, plain);
}
public static String encryptMe(String plain) {
byte[] plainStr = plain.getBytes();
byte[] keyStr = getSHA256(key).getBytes();
// byte[] ivStr = iv.getBytes();//
System.out.println("key str = "+Strings.fromByteArray(keyStr));
try {
byte[] encBytes = encrypt(plainStr, keyStr/*
* , ivStr
*/);
strEncResult= Base64.toBase64String(encBytes);
//strEncResult = new String(encbase);
} catch (Exception e) {
e.printStackTrace();
}
return strEncResult;
}
public static String decryptMe(String cipherText) {
try {
byte[] dcrByte = Base64.decode(cipherText);
byte[] dec = decrypt(dcrByte, getSHA256(key).getBytes()/*
* ,iv.getBytes
* ()
*/);
strDcrResult = Strings.fromByteArray(dec);
} catch (Exception e) {
e.printStackTrace();
}
return strDcrResult;
}
I need advice. I zip and crypt SOAP message on web service and client side.
Client is winforms app.
If I only crypt SOAP message, it works good.
If I only zip SOAP message it also works good.
I use SOAP extension on crypt and zip SOAP.
I use AES - Advanced Encryption Standard - Rijndael and on compresion I use SharpZipLib from http://sourceforge.net/projects/sharpdevelop/.
The problem is I send dataset on client.
Firstly I zip and secondly encrypt SOAP on web service side.
Send on client.
On client side I load XML from stream. But it finish with this error :
Data at the root level is invalid. Line 1, position 2234.
Here is the code, where I load XML from stream:
var doc = new XmlDocument();
using (var reader = new XmlTextReader(inputStream))
{
doc.Load(reader);
}
Any advice ? Thank you...
Here are methods on web service side which zip and crypt SOAP :
//encrypt string
private static string EncryptString(string #string, string initialVector, string salt, string password,
string hashAlgorithm, int keySize, int passwordIterations)
{
byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(#string);
var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
var symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes);
using (var memStream = new MemoryStream())
{
var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
var serializer = new XmlSerializer(typeof(byte[]));
var sb = new StringBuilder();
TextWriter writer = new StringWriter(sb);
serializer.Serialize(writer, memStream.ToArray());
writer.Flush();
var doc = new XmlDocument();
doc.LoadXml(sb.ToString());
if (doc.DocumentElement != null) return doc.DocumentElement.InnerXml;
}
return "";
}
//zip string
private static byte[] ZipArray(string stringToZip)
{
byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToZip);
var ms = new MemoryStream();
// SharpZipLib.Zip,
var zipOut = new ZipOutputStream(ms);
var zipEntry = new ZipEntry("ZippedFile");
zipOut.PutNextEntry(zipEntry);
zipOut.SetLevel(7);
zipOut.Write(inputByteArray, 0, inputByteArray.Length);
zipOut.Finish();
zipOut.Close();
return ms.ToArray();
}
//zip and encrypt SOAP
public virtual Stream OutSoap(string[] soapElement, Stream inputStream)
{
#region Load XML from SOAP
var doc = new XmlDocument();
using (XmlReader reader = XmlReader.Create(inputStream))
{
doc.Load(reader);
}
var nsMan = new XmlNamespaceManager(doc.NameTable);
nsMan.AddNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");
#endregion Load XML from SOAP
#region Zip SOAP
XmlNode bodyNode = doc.SelectSingleNode(#"//soap:Body", nsMan);
bodyNode = bodyNode.FirstChild.FirstChild;
while (bodyNode != null)
{
if (bodyNode.InnerXml.Length > 0)
{
// Zip
byte[] outData = ZipArray(bodyNode.InnerXml);
bodyNode.InnerXml = Convert.ToBase64String(outData);
}
bodyNode = bodyNode.NextSibling;
}
#endregion Zip SOAP
#region Crypt SOAP
foreach (string xPathQuery in soapElement)
{
XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
if (nodesToEncrypt != null)
foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
{
//Encrypt
nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml,
user.IV, user.Salt, user.Password, user.HashType,
user.KeySize, user.PasswordIterations);
}
}
#endregion Crypt SOAP
inputStream.Position = 0;
var settings = new XmlWriterSettings { Encoding = Encoding.UTF8 };
using (XmlWriter writer = XmlWriter.Create(inputStream, settings))
{
doc.WriteTo(writer);
return inputStream;
}
}
Here is a code on client side which decrypt and uzip SOAP :
//decrypt string
private static string DecryptString(string #string, string initialVector, string salt, string password,
string hashAlgorithm, int keySize, int passwordIterations)
{
byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
byte[] cipherTextBytes = Convert.FromBase64String(#string);
var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes);
using (var memStream = new MemoryStream(cipherTextBytes))
{
var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read);
var plainTextBytes = new byte[cipherTextBytes.Length];
int byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
}
}
//unzip string
private static byte[] UnzipArray(string stringToUnzip)
{
byte[] inputByteArray = Convert.FromBase64String(stringToUnzip);
var ms = new MemoryStream(inputByteArray);
var ret = new MemoryStream();
// SharpZipLib.Zip
var zipIn = new ZipInputStream(ms);
var theEntry = zipIn.GetNextEntry();
var buffer = new Byte[2048];
int size = 2048;
while (true)
{
size = zipIn.Read(buffer, 0, buffer.Length);
if (size > 0)
{
ret.Write(buffer, 0, size);
}
else
{
break;
}
}
return ret.ToArray();
}
public virtual Stream InSoap(Stream inputStream, string[] soapElement)
{
#region Load XML from SOAP
var doc = new XmlDocument();
using (var reader = new XmlTextReader(inputStream))
{
doc.Load(reader);
}
var nsMan = new XmlNamespaceManager(doc.NameTable);
nsMan.AddNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");
#endregion Load XML from SOAP
#region Decrypt SOAP
foreach (string xPathQuery in soapElement)
{
XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
if (nodesToEncrypt != null)
foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
{
nodeToEncrypt.InnerXml = DecryptString(nodeToEncrypt.InnerXml, saltPhrase, passwordPhrase, initialVector,
hashAlgorithm, passwordIterations, keySize);
}
}
#endregion Decrypt SOAP
#region UnZip SOAP
XmlNode node = doc.SelectSingleNode("//soap:Body", nsMan);
node = node.FirstChild.FirstChild;
while (node != null)
{
if (node.InnerXml.Length > 0)
{
byte[] outData = UnzipArray(node.InnerXml);
string sTmp = Encoding.UTF8.GetString(outData);
node.InnerXml = sTmp;
}
node = node.NextSibling;
}
#endregion UnZip SOAP
var retStream = new MemoryStream();
doc.Save(retStream);
return retStream;
}
strong text
I'm not sure why your unencrypted xml won't parse, but I think you're first step should be to dump the decrypted data to the terminal to see exactly what text you're getting back. Perhaps the process corrupts your data somehow, or you have an encoding issue.
Alternatively, you could configure your server to use https and gzip compression to achieve the same goal. You won't loose any security with this approach and this is by far the more standard way to do things. You can also have a look at MS's support for the WS-Security standard