Intro
I'm trying to encrypt and decrypt texts and sometimes, especially for larger texts, random characters appear within the decrypted text. I'm using AES cryptography within the System.Security.Cryptography
namespace and the text I'm trying to encrypt at the moment would be a URL and some info, such as the page title. I've provided an example below and what I've attempted. I've also written the two encryption and decryption methods, minus any lines that output to the Debug Window. The Key and IV used shouldn't be a problem as, for now, they would be constant.
I think it would be wise for me to point out that it encrypts and decrypts 18/01/2013;18/01/2013
, in a separate occurrence, as expected.
Example
Say I wanted to decrypt this text:
Barnabe Googes Information & Homepage | Search and Research on BarnabeGooge.com;18/01/2013;18/01/2013;;http://www.googe.com
By default it uses UTF-8 and it would encrypt to:
뤟羜ڮ胂淺弊놛荧ꠃ錺槝ヸ蘜ầᄼꕒヘ⍩㗪潺뱂施㒞ꨛ殳硪픴ی뿨춃�燲ᯁﱪ뙊힓琲鯖嶑⨹갂Ѭ쳀鿜�྄䋖⭫ퟂ㪏�荾ꆺשּ붹梾麦膛
And decrypts back to:
Barnabe Googes Information & Homepage | Search and Research on B���Ax2�!��f�M]18/01/20�;18/01[�;>َ�l?����m��*-��+��^A[=�
What I've attempted
- I've attempted to change to other Encodings, but UTF-8 seem to affect the decrypted text the least.
- Changed to different types of padding, but
Padding.Zeros
seems the best. I also can't usePadding.None
because it throws aNotSupportedException: bad data length
. - Changed the
Mode
to CBC (Not that it should matter). - Flush/Close CryptoStream so it could flush the final block, or something.
- Just in case the fault rested with the title, I used
WebUtility.HtmlDecode()
to decode the title, but it didn't affect it.
Encryption Method
The encryption below uses AES Encryption, as you can see. I want to point out that key
and IV
are two global strings within the same class as both of the Encryption and Decryption methods. The reason I've done this is to mess around with different encodings and CryptographyServiceProviders
, just if by chance a random change works. Please ignore these as they are constant and won't affect the final encryption/decryption.
public static byte[] EncryptStringToBytes(string plainText, Encoding Enc)
{
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
byte[] encrypted;
using (AesCryptoServiceProvider tdsAlg = new AesCryptoServiceProvider())
{
tdsAlg.Key = (byte[])Enc.GetBytes(key).Take(tdsAlg.Key.Length).ToArray();
tdsAlg.IV = (byte[])Enc.GetBytes(IV).Take(tdsAlg.IV.Length).ToArray();
tdsAlg.Padding = PaddingMode.Zeros;
tdsAlg.Mode = CipherMode.CBC;
ICryptoTransform encryptor = tdsAlg.CreateEncryptor(tdsAlg.Key, tdsAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
csEncrypt.Close();
}
}
}
return encrypted;
}
Decryption Method
public static string DecryptStringFromBytes(byte[] cipherText,Encoding Enc)
{
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
string plaintext = null;
using (AesCryptoServiceProvider tdsAlg = new AesCryptoServiceProvider())
{
tdsAlg.Key = (byte[])Enc.GetBytes(key).Take(tdsAlg.Key.Length).ToArray();
tdsAlg.IV = (byte[])Enc.GetBytes(IV).Take(tdsAlg.IV.Length).ToArray() ;
tdsAlg.Padding = PaddingMode.Zeros;
tdsAlg.Mode = CipherMode.CBC;
ICryptoTransform decryptor = tdsAlg.CreateDecryptor();
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt,true))
{
plaintext = srDecrypt.ReadToEnd().Replace("\0","");
csDecrypt.Close();
return plaintext.Replace("\0",string.Empty);
}
}
}
}
return plaintext;
}
Bootnote
Just in case it matters, I'm using this to get the title of the webpage, but as I've mentioned using HtmlDecode doesn't affect it.
WebClient x = new WebClient();
string source = x.DownloadString(Url);
x.Dispose();
string title= Regex.Match(source, @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>", RegexOptions.IgnoreCase).Groups["Title"].Value;
title = title.Replace(";", " ");
return title;
Encoding.Utf8.GetString()
orGetBytes()
, I never knew about base64. – Omniscient