I'm trying to set up a messing server for me and my friends and I ran into issues with RSA Decryption.
The correct keys are used
If I enable OAEP padding I get a error that simply states "OAEPpadding"
I'm losing my mind on this bug, I'm posting the script below.
Encryption works fine, its just decryption that's problematic
Please Help
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Xml.Serialization;
namespace Server_WIN_
{
class Program
{
public static XmlSerializer xs = new XmlSerializer(typeof(RSAParameters));
public static TcpListener server = new TcpListener(IPAddress.Parse("192.168.1.93"), 78);
public static TcpClient client = null;
public static NetworkStream canwetalk = null;
public static RSACryptoServiceProvider csp = new RSACryptoServiceProvider(4096);
public static RSAParameters publickey;
public static RSAParameters privatekey;
static Program()
{
server.Start();
csp.PersistKeyInCsp = false;
publickey = csp.ExportParameters(false);
privatekey = csp.ExportParameters(true);
client = server.AcceptTcpClient();
canwetalk = client.GetStream();
}
public static void Main(string[] args)
{
string strHostName = "";
strHostName = Dns.GetHostName();
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
Random ran = new Random();
HashAlgorithm sha = SHA256.Create();
string msg = "";
byte[] buffer = new byte[4096];
msg = "test";
msg = Encrypt(msg);
msg = Decrypt(msg);
Console.WriteLine(msg);
}
public static string PublicKeyString()
{
byte[] bytes = new byte[4096];
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, publickey);
return sw.ToString();
}
public static string PrivateKeyString()
{
byte[] bytes = new byte[4096];
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, privatekey);
return sw.ToString();
}
public static string Encrypt(string msg)
{
csp.ImportParameters(publickey);
byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);
byte[] cipher = csp.Encrypt(data, false);
return System.Text.Encoding.ASCII.GetString(cipher);
}
public static string Decrypt(string msg)
{
try
{
csp.ImportParameters(privatekey);
byte[] decrypted = csp.Decrypt(System.Text.Encoding.ASCII.GetBytes(msg), false);
return System.Text.Encoding.Unicode.GetString(decrypted);
}
catch(CryptographicException e)
{
string p = e.ToString();
Console.WriteLine(p);
}
return "";
}
public static void ExportPublicKey()
{
string msg = PublicKeyString();
byte[] buffer = new byte[4096];
byte[] msg1 = System.Text.Encoding.ASCII.GetBytes(msg);
canwetalk.Write(msg1, 0, msg1.Length);
}
public static void ToStream(string msg, bool Encryption)
{
if (Encryption)
{
msg = Encrypt(msg);
byte[] msgbytes = System.Text.Encoding.ASCII.GetBytes(msg);
canwetalk.Write(msgbytes, 0, msgbytes.Length);
}
else
{
byte[] msgbytes = System.Text.Encoding.ASCII.GetBytes(msg);
canwetalk.Write(msgbytes, 0, msgbytes.Length);
}
}
public static string ReadStream()
{
byte[] buffer = new byte[4096];
int i = canwetalk.Read(buffer,0,buffer.Length);
return System.Text.Encoding.ASCII.GetString(buffer,0,i);
}
}
You can find this stackoverflow question helpful, but it's quite out of date Error occurred while decoding OAEP padding
Don't use the same provider. Do this instead:
var publicKey = RSA.Create();
publicKey.ImportParameters(PUB_PARAMS);
var privateKey = RSA.Create();
privateKey.ImportParameters(PRIV_PARAMS);
Related
I'm trying to implement an asymmetric cryptography approach using RSA algorithm
for that, I'm using the following class library from Microsoft System.Security.Cryptography
This Image Source
so based on public-key sharing, This is my architecture
Basically, I've three standalone applications
Encryption/Decryption Service, which is a class library.
WPF Application to encrypt plain text to ciphertext.
Console Application to decrypt cipher text to plain text.
so this is my Encryption/Decryption Service Backbone
public class EncryptDecryptService : IEncryptDecryptService
{
private static RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
private RSAParameters _privateKey;
private RSAParameters _publicKey;
public EncryptDecryptService()
{
_privateKey = csp.ExportParameters(true);
_publicKey = csp.ExportParameters(false);
}
public void WritePrivateKey(string _privatePath)
{
TextWriter _privateKeyTxt = new StreamWriter(_privatePath);
_privateKeyTxt.Write(GeneratePrivateKey());
_privateKeyTxt.Close();
}
public void WritePublicKey(string _publicPath)
{
TextWriter _publicKeyTxt = new StreamWriter(_publicPath);
_publicKeyTxt.Write(GeneratePublicKey());
_publicKeyTxt.Close();
}
public string GeneratePublicKey()
{
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, _publicKey);
return sw.ToString();
}
public string GeneratePrivateKey()
{
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, _privateKey);
return sw.ToString();
}
public string EncryptText(string plainText, string wpfPrivateKeyPath, string consolePublicKeyPath)
{
csp = new RSACryptoServiceProvider();
var consoleAppPublicKey = CovertRSAXMLtoRSAParam(consolePublicKeyPath, false);
var wpfAppPrivateKey = CovertRSAXMLtoRSAParam(wpfPrivateKeyPath, true);
csp.ImportParameters(consoleAppPublicKey);
csp.ImportParameters(wpfAppPrivateKey);
var data = Encoding.Unicode.GetBytes(plainText);// sample
var cypher = csp.Encrypt(data, false);
return Convert.ToBase64String(cypher);
}
public string DecryptText(string cypherText, string wpfPublicKeyPath, string consolePrivateKeyPath)
{
var dataBytes = Convert.FromBase64String(cypherText);
var consoleAppPrivateKey = CovertRSAXMLtoRSAParam(consolePrivateKeyPath, true);
var wpfAppPublicKey = CovertRSAXMLtoRSAParam(wpfPublicKeyPath, false);
csp.ImportParameters(consoleAppPrivateKey);
csp.ImportParameters(wpfAppPublicKey);
var plainText = csp.Decrypt(dataBytes, false);
return Encoding.Unicode.GetString(plainText);
}
public static RSAParameters CovertRSAXMLtoRSAParam(string _location, bool isExport)
{
string xmlContent = System.IO.File.ReadAllText(_location);
RSAParameters _publicKey = new RSAParameters();
CspParameters cspParam = new CspParameters();
cspParam.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider key = new RSACryptoServiceProvider(cspParam);
key.FromXmlString(xmlContent);
_publicKey = key.ExportParameters(isExport);
return _publicKey;
}
}
Like this way I'm generating the ciphertext for a plain text in WPF application
private void Button_Click(object sender, RoutedEventArgs e)
{
var wpfPrivateKeyPath = "C:\\SERVICE\\keys\\wpf_private_key.txt";
var consolePublicKeyPath = "C:\\SERVICE\\keys\\console_public_key.txt";
objWebservice.WritePrivateKey(wpfPrivateKeyPath);
objWebservice.WritePublicKey(consolePublicKeyPath);
string _plainText = PlainTextValue.Text;
string _encryptedText = objWebservice.EncryptText(_plainText, wpfPrivateKeyPath, consolePublicKeyPath);
EncryptedTextValue.Text = _encryptedText;
}
Then that ciphertext I'm trying to convert back to previous plain text in the following way.
public static void Main(string[] args)
{
EncryptDecryptService decryptService = new EncryptDecryptService();
string encryptedText = "SDSFDSFSDFDSFSsdfsdf";
var wpfPublicKeyPath = "C:\\SERVICE\\keys\\wpf_public_key.txt";
var consolePrivateKeyPath = "C:\\SERVICE\\keys\\console_private_key.txt";
decryptService.WritePrivateKey(consolePrivateKeyPath);
decryptService.WritePublicKey(wpfPublicKeyPath);
var plaintText = decryptService.DecryptText(encryptedText, wpfPublicKeyPath, consolePrivateKeyPath);
Console.WriteLine(plaintText);
Console.ReadLine();
}
this is where an error occurring when it's going to decrypt as in this image.
what did I missed here, please if can guide me to make this correct :)
I've got some class for encrypting and signing emails.
Signing process is going without problems , but when I trying to
encrypt the message using "Encrypt" method on EnvelopedCms instance ,I've got exception with information "invalid cryptographic message type".
I've tried to specify ContentType in contentInfo by setting
Oid="1.2.840.113549.1.7.2",which is "signedData" type (according to msdn library), but is not working.
public static void SignAndEncryptMessage(MailMessage message, X509Certificate2 signingCertificate, X509Certificate2 encryptionCertificate)
{
string content = BuildMessageContent(message);
content = SignContent(content, message.BodyEncoding, signingCertificate, encryptionCertificate);
Stream encryptedStream = Encrypt(content, message.BodyEncoding, encryptionCertificate);
AlternateView av = new AlternateView(encryptedStream,
"application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
message.AlternateViews.Add(av);
message.Body = null;
message.Attachments.Clear();
}
public static void SignMessage(MailMessage message, X509Certificate2 signingCertificate)
{
string content = BuildMessageContent(message);
content = SignContent(content, message.BodyEncoding, signingCertificate, null);
MemoryStream stream = new MemoryStream();
byte[] mimeMessage = Encoding.ASCII.GetBytes("This is a multi-part message in MIME format.\r\n\r\n");
stream.Write(mimeMessage, 0, mimeMessage.Length);
byte[] contentBytes = message.BodyEncoding.GetBytes(content);
stream.Write(contentBytes, 0, contentBytes.Length);
stream.Position = 0;
AlternateView av = new AlternateView(stream,
"multipart/signed; boundary=\"--PTBoundry=3\";protocol=\"application/x-pkcs7-signature\"; micalg=SHA1;");
av.TransferEncoding = TransferEncoding.SevenBit;
message.AlternateViews.Add(av);
message.Body = null;
message.Attachments.Clear();
}
public static Stream Encrypt(string content, Encoding contentEncoding, X509Certificate2 encryptionCertificate)
{
const string signatureBoundry2 = "--PTBoundry=3";
StringBuilder fullUnencryptedMessageBuilder = new StringBuilder();
fullUnencryptedMessageBuilder.Append("Content-Type: ");
fullUnencryptedMessageBuilder.Append("multipart/signed; ");
fullUnencryptedMessageBuilder.Append(" boundary=\"");
fullUnencryptedMessageBuilder.Append(signatureBoundry2);
fullUnencryptedMessageBuilder.Append("\"; protocol=\"application/x-pkcs7-signature\"; micalg=SHA1; ");
fullUnencryptedMessageBuilder.Append("\r\n");
fullUnencryptedMessageBuilder.Append("Content-Transfer-Encoding: ");
fullUnencryptedMessageBuilder.Append(TransferEncoding.SevenBit);
fullUnencryptedMessageBuilder.Append("\r\n\r\n");
fullUnencryptedMessageBuilder.Append(content);
string fullUnencryptedMessage = fullUnencryptedMessageBuilder.ToString();
byte[] encryptedBytes = DoEncrypt(fullUnencryptedMessage, contentEncoding, encryptionCertificate);
MemoryStream stream = new MemoryStream(encryptedBytes);
return stream;
}
private static byte[] DoEncrypt(string message, Encoding encoding, X509Certificate2 encryptionCertificates)
{
byte[] messageBytes = encoding.GetBytes(message);
var contentNfo = new ContentInfo(messageBytes);
var encms = new EnvelopedCms(contentNfo);
var recipient = new CmsRecipient(encryptionCertificates);
try
{
encms.Encrypt(recipient);
var asdf = encms.RecipientInfos;
return encms.Encode();
}
catch (Exception e)
{
throw e;
}
}
public static byte[] Decrypt(Stream stream)
{
byte[] cont = new byte[stream.Length];
stream.Read(cont, 0, cont.Length);
return Decrypt(cont);
}
public static byte[] Decrypt(byte[] message)
{
EnvelopedCms envelopedCms = new EnvelopedCms();
envelopedCms.Decode(message);
envelopedCms.Decrypt();
return envelopedCms.ContentInfo.Content;
}
public static string BuildMessageContent(MailMessage msg)
{
string messageBody = msg.Body;
if ((string.IsNullOrEmpty(messageBody) || string.Empty == messageBody.Trim()) && msg.AlternateViews.Count > 0)
{
messageBody = Encoding.UTF8.GetString(msg.AlternateViews[0].ContentStream.ToByteArray());
}
const string messageBoundry = "--PTBoundry=2";
StringBuilder message = new StringBuilder();
message.Append("\r\n");
message.Append("\r\n");
message.Append("--");
message.Append(messageBoundry + "\r\n");
message.Append(string.Format("Content-Type: {0}; charset={1}\r\n", msg.IsBodyHtml ? "text/html" : "text/plain", msg.BodyEncoding.WebName));
message.Append("Content-Transfer-Encoding: ");
message.Append(TransferEncoding.QuotedPrintable);
message.Append("\r\n\r\n");
message.Append(messageBody);
message.Append("\r\n");
foreach (Attachment attachment in msg.Attachments)
{
BinaryReader br = new BinaryReader(attachment.ContentStream);
byte[] buff = br.ReadBytes((int)attachment.ContentStream.Length);
String filecontent =
Convert.ToBase64String(buff, Base64FormattingOptions.InsertLineBreaks);
message.Append("--");
message.Append(messageBoundry);
message.Append("\r\n");
message.Append("Content-Type: ");
message.Append("application/octet-stream;");
message.Append(string.Format("name=\"{0}\"", attachment.Name));
message.Append("\r\n");
if (attachment.ContentDisposition.Inline)
{
message.Append("Content-Disposition: inline");
message.Append("\r\n");
message.Append("Content-ID: <").Append(attachment.ContentId).Append(">");
message.Append("\r\n");
}
message.Append("Content-Transfer-Encoding: base64\r\n\r\n");
message.Append(filecontent);
message.Append("\r\n\r\n");
}
message.Append("--");
message.Append(messageBoundry);
message.Append("--\r\n");
return message.ToString();
}
public static byte[] GetSignature(string message, Encoding encoding, X509Certificate2 signingCertificate, X509Certificate2 encryptionCertificate)
{
byte[] messageBytes = encoding.GetBytes(message);
SignedCms signedCms = new SignedCms(new ContentInfo(messageBytes), true);
if (!signingCertificate.HasPrivateKey)
{
_log.Error("Certyfikat do podpisywania nie posiada klucza prywatnego!");
}
CmsSigner cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signingCertificate) { IncludeOption = X509IncludeOption.WholeChain };
if (encryptionCertificate != null)
{
cmsSigner.Certificates.Add(encryptionCertificate);
}
Pkcs9SigningTime signingTime = new Pkcs9SigningTime();
cmsSigner.SignedAttributes.Add(signingTime);
try
{
signedCms.ComputeSignature(cmsSigner, false);
return signedCms.Encode();
}
finally
{
cmsSigner.Certificates.Clear();
}
}
public static string SignContent(string content, Encoding contentEncoding, X509Certificate2 signingCertificate, X509Certificate2 encryptionCertificate)
{
const string signatureBoundry = "--PTBoundry=2";
const string signatureBoundry2 = "--PTBoundry=3";
StringBuilder fullUnsignedMessageBuilder = new StringBuilder();
fullUnsignedMessageBuilder.Append("Content-Type: ");
fullUnsignedMessageBuilder.Append("multipart/mixed;");
fullUnsignedMessageBuilder.Append(" boundary=\"");
fullUnsignedMessageBuilder.Append(signatureBoundry);
fullUnsignedMessageBuilder.Append("\"\r\n");
fullUnsignedMessageBuilder.Append("Content-Transfer-Encoding: ");
fullUnsignedMessageBuilder.Append(TransferEncoding.SevenBit);
fullUnsignedMessageBuilder.Append("\r\n");
fullUnsignedMessageBuilder.Append(content);
string fullUnsignedMessage = fullUnsignedMessageBuilder.ToString();
byte[] signature = GetSignature(fullUnsignedMessage, contentEncoding, signingCertificate, encryptionCertificate);
StringBuilder signedMessageBuilder = new StringBuilder();
signedMessageBuilder.Append("--");
signedMessageBuilder.Append(signatureBoundry2);
signedMessageBuilder.Append("\r\n");
signedMessageBuilder.Append(fullUnsignedMessage);
signedMessageBuilder.Append("\r\n");
signedMessageBuilder.Append("--");
signedMessageBuilder.Append(signatureBoundry2);
signedMessageBuilder.Append("\r\n");
signedMessageBuilder.Append("Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\r\n");
signedMessageBuilder.Append("Content-Transfer-Encoding: base64\r\n");
signedMessageBuilder.Append("Content-Disposition: attachment; filename=\"smime.p7s\"\r\n\r\n");
signedMessageBuilder.Append(Convert.ToBase64String(signature));
signedMessageBuilder.Append("\r\n\r\n");
signedMessageBuilder.Append("--");
signedMessageBuilder.Append(signatureBoundry2);
signedMessageBuilder.Append("--\r\n");
return signedMessageBuilder.ToString();
}
I've used RadPersistenceManager with asp.net and follow the following guide :
http://demos.telerik.com/aspnet-ajax/persistence-framework/examples/custom-storage-provider/defaultcs.aspx.
But when I implement this in my project the following exception appears:
Title: xxxx.aspx, xxxxx Method Name:
Unable to read storage content. Could not find file
'C:\inetpub\wwwroot\XXXX\App_Data\TelerikAspNetRadControlsPersistedState'.
Exception: at
Telerik.Web.UI.PersistenceFramework.AppDataStorageProvider.LoadStateFromStorage(String
key) at Telerik.Web.UI.RadPersistenceManager.LoadState() at GraphicalUserInterface.JobBasket.LoadGridJobBasket()
That's the default storage provider key. If the control is looking for it, then your custom provider is not in effect at all.
Make sure you have everything from the demo, primarily:
the lines that set the custom storage provider:
protected void Page_Init(object sender, EventArgs e)
{
RadPersistenceManager1.StorageProviderKey = CookieName;
RadPersistenceManager1.StorageProvider = new CookieStorageProvider(CookieName);
}
and the custom storage provider itself:
using System;
using System.Linq;
using System.Web;
using Telerik.Web.UI.PersistenceFramework;
using System.IO;
using System.IO.Compression;
using System.Text;
public class CookieStorageProvider : IStateStorageProvider
{
private static readonly Encoding AsciiEncoding = System.Text.Encoding.ASCII;
private static readonly int MaxCookieSize = 4000;
private static readonly int LengthDataByteCount = sizeof(Int32);
private string StorageKey { get; set; }
#region IStateStorageProvider
public CookieStorageProvider(string key)
{
StorageKey = key;
}
public void SaveStateToStorage(string key, string serializedState)
{
HttpCookie cookie = new HttpCookie(StorageKey);
string settingsData = CompressString(serializedState);
if (settingsData.Length > MaxCookieSize)
{
throw new ArgumentOutOfRangeException("Current settings exceed 4k in compressed form! Operation canceled!");
}
cookie.Value = settingsData;
HttpContext.Current.Response.Cookies.Add(cookie);
}
public string LoadStateFromStorage(string key)
{
return DecompressString(HttpContext.Current.Request.Cookies[StorageKey].Value.ToString());
}
#endregion
private string CompressString(string inputString)
{
byte[] outputBytes = null;
byte[] inputBytes = AsciiEncoding.GetBytes(inputString);
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress))
{
zipStream.Write(inputBytes, 0, inputBytes.Length);
}
outputBytes = ms.ToArray();
}
return Convert.ToBase64String(AddDataCount(outputBytes, inputBytes.Length));
}
private string DecompressString(string inputString)
{
string outputString = String.Empty;
byte[] inputBytes = Convert.FromBase64String(inputString);
Int32 lengthDataArray = BitConverter.ToInt32(inputBytes, inputBytes.Length - LengthDataByteCount);
byte[] outputBytes = new byte[lengthDataArray];
using (MemoryStream ms = new MemoryStream(RemoveDataCount(inputBytes)))
{
using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress))
{
zipStream.Read(outputBytes, 0, outputBytes.Length);
}
outputString = AsciiEncoding.GetString(outputBytes);
}
return outputString;
}
private byte[] AddDataCount(byte[] inputArray, Int32 length)
{
byte[] lengthDataArray = BitConverter.GetBytes(length);
Array.Resize<byte>(ref inputArray, inputArray.Length + LengthDataByteCount);
Array.Copy(lengthDataArray, 0, inputArray, inputArray.Length - LengthDataByteCount, LengthDataByteCount);
return inputArray;
}
private byte[] RemoveDataCount(byte[] inputArray)
{
Array.Resize<byte>(ref inputArray, inputArray.Length - LengthDataByteCount);
return inputArray;
}
}
The different between the demo and my example that I need to load the persistence configurations on page load instead of load button. so it seems some times the CookieStorageProvider not initiated in Page_Init, so I added it in page_load instead.
I am storing my DataTable in a file using the function given below which i had taken from a website. The code works well.
The problem is:
I want to apply some sort of encryption here. How can i achieve that?
public void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
stream.Close();
}
}
catch (Exception ex)
{
//Log exception here
}
}
Any help is highly appreciated.
Thanks
Encrypt/Decrypt your streamed XML file with the given below class:
You can use another encryption strategy it is depending on your requirements.
public static class EncryptionManagement
{
private static SymmetricAlgorithm encryption;
private const string password = "admin";
private const string Mkey = "MY SECRET KEY";
private static void Init()
{
encryption = new RijndaelManaged();
var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Mkey));
encryption.Key = key.GetBytes(encryption.KeySize / 8);
encryption.IV = key.GetBytes(encryption.BlockSize / 8);
encryption.Padding = PaddingMode.PKCS7;
}
public static void Encrypt(Stream inStream, Stream OutStream)
{
Init();
var encryptor = encryption.CreateEncryptor();
inStream.Position = 0;
var encryptStream = new CryptoStream(OutStream, encryptor, CryptoStreamMode.Write);
inStream.CopyTo(encryptStream);
encryptStream.FlushFinalBlock();
}
public static void Decrypt(Stream inStream, Stream OutStream)
{
Init();
var encryptor = encryption.CreateDecryptor();
inStream.Position = 0;
var encryptStream = new CryptoStream(inStream, encryptor, CryptoStreamMode.Read);
encryptStream.CopyTo(OutStream);
OutStream.Position = 0;
}
}
I have following code that works fine when I use a four letter word as input, E.g. “Test”. When the input is not a multiple of 4, it fails E.g. “MyTest”.
Eexception: Invalid length for a Base-64 char array.
QUESTIONS
Is it guaranteed that the encrypted result will be always compatible to a Unicode string (without any loss). If yes I can use UTF encoding instead of Base64? What's the difference between UTF8/UTF16 and Base64 in terms of encoding
How can add padding so that we get correct result (after decryption) even if the input is not a multiple of 4?
MAIN PRGORAM
class Program
{
static void Main(string[] args)
{
string valid128BitString = "AAECAwQFBgcICQoLDA0ODw==";
string inputValue = "MyTest";
string keyValue = valid128BitString;
byte[] byteValForString = Convert.FromBase64String(inputValue);
EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue);
EncryptResult encyptedValue = new EncryptResult();
string resultingIV = "4uy34C9sqOC9rbV4GD8jrA==";
if (String.Equals(resultingIV,result.IV))
{
int x = 0;
}
encyptedValue.IV = resultingIV;
encyptedValue.EncryptedMsg = result.EncryptedMsg;
string finalResult = Convert.ToBase64String(Aes128Utility.DecryptData(encyptedValue, keyValue));
Console.WriteLine(finalResult);
if (String.Equals(inputValue, finalResult))
{
Console.WriteLine("Match");
}
else
{
Console.WriteLine("Differ");
}
Console.ReadLine();
}
}
AES Crypto UTILITY
public static class Aes128Utility
{
private static byte[] key;
public static EncryptResult EncryptData(byte[] rawData, string strKey)
{
EncryptResult result = null;
if (key == null)
{
if (!String.IsNullOrEmpty(strKey))
{
key = Convert.FromBase64String((strKey));
result = Encrypt(rawData);
}
}
else
{
result = Encrypt(rawData);
}
return result;
}
public static byte[] DecryptData(EncryptResult encryptResult, string strKey)
{
byte[] origData = null;
if (key == null)
{
if (!String.IsNullOrEmpty(strKey))
{
key = Convert.FromBase64String(strKey);
origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV));
}
}
else
{
origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV));
}
return origData;
}
private static EncryptResult Encrypt(byte[] rawData)
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
aesProvider.Key = key;
aesProvider.Mode = CipherMode.CBC;
aesProvider.Padding = PaddingMode.PKCS7;
aesProvider.IV = Convert.FromBase64String("4uy34C9sqOC9rbV4GD8jrA==");
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream encStream = new CryptoStream(memStream, aesProvider.CreateEncryptor(), CryptoStreamMode.Write);
encStream.Write(rawData, 0, rawData.Length);
encStream.FlushFinalBlock();
EncryptResult encResult = new EncryptResult();
encResult.EncryptedMsg = Convert.ToBase64String(memStream.ToArray());
encResult.IV = Convert.ToBase64String(aesProvider.IV);
return encResult;
}
}
}
private static byte[] Decrypt(byte[] encryptedMsg, byte[] iv)
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
aesProvider.Key = key;
aesProvider.IV = iv;
aesProvider.Mode = CipherMode.CBC;
aesProvider.Padding = PaddingMode.PKCS7;
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream decStream = new CryptoStream(memStream, aesProvider.CreateDecryptor(), CryptoStreamMode.Write);
decStream.Write(encryptedMsg, 0, encryptedMsg.Length);
decStream.FlushFinalBlock();
return memStream.ToArray();
}
}
}
}
DTO
public class EncryptResult
{
public string EncryptedMsg { get; set; }
public string IV { get; set; }
}
REFERENCES:
How to create byte[] with length 16 using FromBase64String
Getting incorrect decryption value using AesCryptoServiceProvider
If you are encrypting, then encoding Base64 for me doesn't add anything useful, instead it brings the problems you face.
As for the padding, a solution i have seen is to create a new byte[] that is indeed a multiple of 4 and copy the source byte[] to that new byte[].
So, something like this:
if (rawdata.Length % 16 !=0)
{
newSource = new byte[source.Length + 16 - source.Length % 16];
Array.Copy(source, newSource, source.Length);
}
Base64 is a way of representing binary values as text so that you do not conflict with common control codes like \x0A for newline or \0 for a string terminator. It is NOT for turning typed text in to binary.
Here is how you should be passing the text in and getting it back out. You can replace UTF8 with whatever encoding you want, but you will need to make sure the Encoding.Whatever.GetBytes is the same encoding as the Encoding.Whatever.GetString
class Program
{
static void Main(string[] args)
{
string valid128BitString = "AAECAwQFBgcICQoLDA0ODw==";
string inputValue = "MyTest";
string keyValue = valid128BitString;
//Turns our text in to binary data
byte[] byteValForString = Encoding.UTF8.GetBytes(inputValue);
EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue);
EncryptResult encyptedValue = new EncryptResult();
//(Snip)
encyptedValue.IV = resultingIV;
encyptedValue.EncryptedMsg = result.EncryptedMsg;
string finalResult = Encoding.UTF8.GetString(Aes128Utility.DecryptData(encyptedValue, keyValue));
Console.WriteLine(finalResult);
if (String.Equals(inputValue, finalResult))
{
Console.WriteLine("Match");
}
else
{
Console.WriteLine("Differ");
}
Console.ReadLine();
}
}