I don't know what I'm doing wrong but I've been trying to get this thing working for about 4 hours now and I just can't get it to work... this just gives me the error: "Please suppy a correct password" when I try to decrypt.
Encryption seems to work fine though.
Any suggestions? :<
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Security;
using AesApp.Rijndael;
using System.Linq;
internal class FileEncryption
{
private static string password = pw;
internal static void Encrypt(string inputfile, string outputfile)
{
byte[] encryptedPassword;
// Create a new instance of the RijndaelManaged
// class. This generates a new key and initialization
// vector (IV).
using (var algorithm = new RijndaelManaged())
{
algorithm.KeySize = 256;
algorithm.BlockSize = 128;
// Encrypt the string to an array of bytes.
encryptedPassword = Cryptology.EncryptStringToBytes(
password, algorithm.Key, algorithm.IV);
}
string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
Cryptology.EncryptFile(#inputfile, #outputfile, chars);
}
internal static void Decrypt(string #inputfile, string #outputfile)
{
byte[] encryptedPassword;
// Create a new instance of the RijndaelManaged
// class. This generates a new key and initialization
// vector (IV).
using (var algorithm = new RijndaelManaged())
{
algorithm.KeySize = 256;
algorithm.BlockSize = 128;
// Encrypt the string to an array of bytes.
encryptedPassword = Cryptology.EncryptStringToBytes(
password, algorithm.Key, algorithm.IV);
}
string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
Cryptology.DecryptFile(#inputfile, #outputfile, chars);
}
}
Reindael.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace AesApp.Rijndael
{
internal sealed class Cryptology
{
private const string Salt = "d5fg4df5sg4ds5fg45sdfg4";
private const int SizeOfBuffer = 1024 * 8;
internal static byte[] EncryptStringToBytes(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 RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged())
{
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var 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;
}
internal static string DecryptStringFromBytes(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("key");
// Declare the string used to hold
// the decrypted text.
string plaintext;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged())
{
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherText))
{
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();
}
}
}
}
return plaintext;
}
internal static void EncryptFile(string inputPath, string outputPath, string password)
{
var input = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
var output = new FileStream(outputPath, FileMode.OpenOrCreate, FileAccess.Write);
// Essentially, if you want to use RijndaelManaged as AES you need to make sure that:
// 1.The block size is set to 128 bits
// 2.You are not using CFB mode, or if you are the feedback size is also 128 bits
var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Salt));
algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);
using (var encryptedStream = new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
{
CopyStream(input, encryptedStream);
}
}
internal static void DecryptFile(string inputPath, string outputPath, string password)
{
var input = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
var output = new FileStream(outputPath, FileMode.OpenOrCreate, FileAccess.Write);
// Essentially, if you want to use RijndaelManaged as AES you need to make sure that:
// 1.The block size is set to 128 bits
// 2.You are not using CFB mode, or if you are the feedback size is also 128 bits
var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Salt));
algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);
try
{
using (var decryptedStream = new CryptoStream(output, algorithm.CreateDecryptor(), CryptoStreamMode.Write))
{
CopyStream(input, decryptedStream);
}
}
catch (CryptographicException)
{
throw new InvalidDataException("Please suppy a correct password");
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
private static void CopyStream(Stream input, Stream output)
{
using (output)
using (input)
{
byte[] buffer = new byte[SizeOfBuffer];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
}
}
}
Not entirely sure, but I think I remember a time when 2 successive calls to encryption gave 2 different results.
Therefore, your two successive calls to EncryptStringToBytes may give 2 different passwords : one for encryption and one for decryption... and this cause the failure.
I am not sure these encryptions are necessary... if you have a password hardcoded, it is always possible to anyone to generate other strings that depend on nothing else. You should use this password directly, instead of crypting it a first time:
internal static void Encrypt(string inputfile, string outputfile)
{
Cryptology.EncryptFile(inputfile, outputfile, password);
}
internal static void Decrypt(string inputfile, string outputfile)
{
Cryptology.DecryptFile(inputfile, outputfile, password);
}
Your Encrypt function seems to be exactly equal to your decrypt function.
Also, why are you converting all bytes to strings and concatenate them? This transformation is not reversible.
string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
Cryptology.EncryptFile(#inputfile, #outputfile, chars);
The Aggregate() function is the cause. It is creating different values each time you run your application.
Related
i have a problem, i tried to fix it myself but i cant.
My program search als .txt files from a directory. Then it read the files and encrypt each file and overwrite the old file. That works fine. Now i want to decrypt the txt files, the following happens:
Here you can see the encrypted text and the decrypted text
So the Problem is, the .txt file becomes encrypted, and the decryption works too, but when i decrypt there dont come the original text. You can see it on the picture, there are coming only wired letters. I cant understand why, i use the same salt and the same password.
Here is my code:
The first 3 snippets are for encryption, the other 3 for decryption.
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine(Inhalt + "\n");
string Verschlüsselterinhalt = Verschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllText(temppfad, Verschlüsselterinhalt);
}
These Part is still working, just upload it to understand it better.
The encryption parts:
static string Verschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
StringBuilder s = new StringBuilder();
foreach (byte item in encrypted)
{
s.Append(item.ToString("X2") + " ");
}
Console.WriteLine("Encrypted: " + s + "\n\n");
return s.ToString();
}
}
static byte[] EncryptStringToBytes(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 RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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;
}
I think to that point all is ok, now I will post the decryption parts.
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine("Inhalt: " + Inhalt + "\n");
string Entschlüsselterinhalt = Entschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllText(temppfad, Entschlüsselterinhalt);
}
static string Entschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Decrypt the bytes to a string.
byte[] originalbytes = Encoding.ASCII.GetBytes(original);
string decrypted = DecryptStringFromBytes(originalbytes, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Decrypted: " + decrypted);
return decrypted;
}
}
static string DecryptStringFromBytes(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("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.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 would be very happy when someone could help me.
UPDATE!!!
I edited now my code, now it looks so:
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine(Inhalt + "\n");
byte[] Verschlüsselterinhalt = Verschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllBytes(temppfad, Verschlüsselterinhalt);
}
static byte[] Verschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
return encrypted;
}
}
I think that part is ok, now on decryption i get an error
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
StreamReader sr = new StreamReader(temppfad);
string Inhalt = sr.ReadToEnd();
Console.WriteLine("Inhalt: " + Inhalt + "\n");
string Entschlüsselterinhalt = Entschlüsseln(Password, Inhalt);
sr.Close();
File.WriteAllText(temppfad, Entschlüsselterinhalt);
}
static string Entschlüsseln(string PW, string original)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
byte[] salt = Encoding.ASCII.GetBytes("0PQUX76U0adfaDADFexA888887Dz3J3X");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(PW, salt);
myRijndael.Key = key.GetBytes(myRijndael.KeySize / 8);
myRijndael.IV = key.GetBytes(myRijndael.BlockSize / 8);
// Decrypt the bytes to a string.
byte[] originalbytes = Encoding.ASCII.GetBytes(original);
string decrypted = DecryptStringFromBytes(originalbytes, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Decrypted: " + decrypted);
return decrypted;
}
}
The error comes here:
Errormessage
Here there full code:
static string DecryptStringFromBytes(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("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.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;
}
Greetings
The issue is you are messing with the encrypted text by doing this
StringBuilder s = new StringBuilder();
foreach (byte item in encrypted)
{
s.Append(item.ToString("X2") + " ");
}
As Damien mentioned you should return a byte array from static string Verschlüsseln(string PW, string original) and use File.WriteAllBytes to write it to file. You can then use File.ReadAllBytes to read it from the file and pass a byte[] into you're decrypt method and you don't need to do anything to do with encoding.
SOLVED
Thank you for your much help, my last error was pretty easy, just a little mistake, here the solution of the part where was the error:
foreach (var file in d2.GetFiles("*.txt"))
{
Console.WriteLine(file.FullName, file.Name);
string temppfad = file.FullName;
byte[] Inhaltsbyte = File.ReadAllBytes(temppfad);
string Entschlüsselterinhalt = Entschlüsseln(Password, Inhaltsbyte);
File.WriteAllText(temppfad, Entschlüsselterinhalt);
}
I want to do AES256 Encryption in .net core 1.1. RijndaelManaged is not supporting with the .net core 1.1. So I'm using here AES aes = new AES.create()
This part of code create the random private key for the encryption
public string GenaratePassPharse()
{
RandomNumberGenerator rngCryptoServiceProvider = RandomNumberGenerator.Create();
byte[] randomBytes = new byte[KEY_SIZE];
rngCryptoServiceProvider.GetBytes(randomBytes);
string plainPassPharse = Convert.ToBase64String(randomBytes);
return plainPassPharse;
}
and here the AES() encryption method. What I want to do is pass my generated key (which is return from above method)instead of the aesAlg.Key as an encryption key.
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 Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.BlockSize = 128;
aesAlg.KeySize = 128;
// 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;
}
And any another way to use AES256 Encryption algorithms?
The full code should be:
public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] iv = null)
{
// Check arguments.
if (plainText == null)
{
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length == 0)
{
throw new ArgumentNullException("Key");
}
// Create an Aes object
// with the specified key and IV.
using (Aes aes = Aes.Create())
{
aes.Key = key;
if (iv == null)
{
iv = new byte[aes.BlockSize / 8];
using (RandomNumberGenerator rngCryptoServiceProvider = RandomNumberGenerator.Create())
{
rngCryptoServiceProvider.GetBytes(iv);
}
}
// Note that we are setting IV, Mode, Padding
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Create an encryptor to perform the stream transform.
using (ICryptoTransform encryptor = aes.CreateEncryptor())
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
// Prepend the IV
cs.Write(iv, 0, iv.Length);
// Here we are setting the Encoding
using (StreamWriter sw = new StreamWriter(cs, Encoding.UTF8))
{
// Write all data to the stream.
sw.Write(plainText);
}
byte[] encrypted = ms.ToArray();
return encrypted;
}
}
}
public static string DecryptBytesToString_Aes(byte[] encrypted, byte[] key)
{
// Check arguments.
if (encrypted == null || encrypted.Length == 0)
{
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length == 0)
{
throw new ArgumentNullException("Key");
}
// Create an Aes object
// with the specified key and IV.
using (Aes aes = Aes.Create())
{
aes.Key = key;
using (MemoryStream ms = new MemoryStream(encrypted))
{
// Read the prepended IV
var iv = new byte[aes.BlockSize / 8];
ms.Read(iv, 0, iv.Length);
// Note that we are setting IV, Mode, Padding
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Create an encryptor to perform the stream transform.
using (ICryptoTransform decrytor = aes.CreateDecryptor())
using (CryptoStream cs = new CryptoStream(ms, decrytor, CryptoStreamMode.Read))
// Here we are setting the Encoding
using (StreamReader sr = new StreamReader(cs, Encoding.UTF8))
{
// Read all data from the stream.
string plainText = sr.ReadToEnd();
return plainText;
}
}
}
}
public static byte[] GenerateAesKey(int bits)
{
using (RandomNumberGenerator rngCryptoServiceProvider = RandomNumberGenerator.Create())
{
byte[] key = new byte[bits / 8];
rngCryptoServiceProvider.GetBytes(key);
return key;
}
}
public static void Main()
{
var key = GenerateAesKey(256);
var encrypted = EncryptStringToBytes_Aes("Hello", key);
var decrypted = DecryptBytesToString_Aes(encrypted, key);
}
This code prepend a random IV to the encrypted stream, and the recovers it from the encrypted stream to decrypt the stream.
It is very important that when you speak of encryption you set everything that can be setted. There must be no questions open. The encryption Mode, the Padding, the Encoding the plaintext must be encoded. Everything!
I get an error in VS Code (running on Ubuntu) in the following code
class Program
{
public static void Main()
{
string originalText = "Test";
try
{
using (Aes myAes = new Aes.Create())
{
string encrypted = StringCipher.Encrypt(originalText, myAes);
string decrypted = StringCipher.Decrypt(encrypted, myAes);
Console.WriteLine(String.Format("Original {0}", originalText));
Console.WriteLine(String.Format("Encrypted {0}", encrypted));
Console.WriteLine(String.Format("Decrypted {0}", decrypted));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
}
The VS Code intellisense is stating that type name 'Create' doesn't exist in type Aes.
Not sure if it's my bad coding but I am essentially following the guide here.
The only difference being I have implemented the encryption / decryption is being implemented in a separate code file here:
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Linq;
namespace EncryptionConsole
{
public static class StringCipher
{
public static string Encrypt(string plainText, Aes aes)
{
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes_Aes(plainText, aes.Key, aes.IV);
string result = Encoding.UTF8.GetString(encrypted);
return result;
}
public static string Decrypt(string cipherText, Aes aes)
{
byte[] cipherTextArray = Encoding.UTF8.GetBytes(cipherText);
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes_Aes(cipherTextArray, aes.Key, aes.IV);
return roundtrip;
}
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 Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
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 Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
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;
}
}
}
I appreciate there may be some glaring mistakes in the above code, this is not really of a concern as I am just exploring at this point.
Any help is greatly appreciated.
Aes.Create() is a static method. You do not need to instanciate it by using the keyword new. If you look at the docs (https://msdn.microsoft.com/en-us/library/bb351532(v=vs.110).aspx), you will see that this method actually returns a newly created AES object for you. This is referred to as "Static Factory Method" in programming terms, and is a common practice/pattern for initializing objects.
Basically calling Aes myAes = new Aes.Create() will try to instanciate the class Create from the namespace or class Aes which explains the error you experience. As stated above you can just use Aes myAes = Aes.Create().
I'm trying to create Aes 256bit Encryption with key in login screen. I need a large encrypted string as i'm using 256bit But it result in small encrypted string.I have checked many samples But all are for Windows desktop application not for windows Phone application. Please help regarding this.
This is my code
namespace SampleEncription
{
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
byte[] encryptedPassword;
// Create a new instance of the RijndaelManaged
// class. This generates a new key and initialization
// vector (IV).
using (var algorithm = new AesManaged())
{
algorithm.KeySize = 256;
algorithm.BlockSize = 128;
// Encrypt the string to an array of bytes.
encryptedPassword = Cryptology.EncryptStringToBytes("Password", algorithm.Key, algorithm.IV);
//string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
string chars = System.Convert.ToBase64String(encryptedPassword);
Debug.WriteLine(chars);
}
}
}
}
one another class named cryptology:
namespace SampleEncription
{
class Cryptology
{
private const string Salt = "603deb1015ca71be2b73aef0857d7781";
private const int SizeOfBuffer = 1024 * 8;
internal static byte[] EncryptStringToBytes(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 RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new AesManaged())
{
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var 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;
}
}
}
instead of
string chars = System.Convert.ToBase64String(encryptedPassword);
do this
Encoding.UTF8.GetString(encryptedPassword, 0, encryptedPassword.Length);
I think wp8 doesn't allow you to use System.Text.Encoding.Default.GetString, you can try to default it to UTF8, which i assume that the cipher text are all in latin characters..
You forgot to flush :)
You are calling encrypted = msEncrypt.ToArray(); before closing and therefore flushing the CryptoStream. As the final block needs to be padded, not all bytes will have been written. If you use a block cipher mode of encryption or an authenticated cipher, it is always required to flush. Only stream cipher modes of encryption may not require you to flush the stream as each bit can be encryption separately.
In your implementation, you should be able to just move msEncrypt.ToArray() below the using scope of the CryptoStream, if I'm not mistaken.
I use the function EncryptStringToBytes to encrypt plain text to array of bytes and
finally convert array of bytes to string and return it then.
I use another function to Decrypt Encrypted text to plaint text.
I try to scramble a text with RC2 but it raises this error:
Rijndael class to encrypt and then decrypt data
Here's the code:
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace RC2CryptoServiceProvider_Examples
{
class MyMainClass
{
static string EncryptStringToBytes(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 Rijndael object
// with the specified key and IV.
using (Rijndael rijAlg = Rijndael.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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 System.Text.Encoding.UTF8.GetString(encrypted);**
}
static string DecryptStringFromBytes(string Codedtext, byte[] Key, byte[] IV)
{
byte[] cipherText = System.Text.Encoding.UTF8.GetBytes(Codedtext);
// 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("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Rijndael object
// with the specified key and IV.
using (Rijndael rijAlg = Rijndael.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.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;
}
public static void Main()
{
try
{
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
string original = "Here is some data to encrypt!";
// Create a new instance of the Rijndael
// class. This generates a new key and initialization
// vector (IV).
using (Rijndael myRijndael = Rijndael.Create())
{
// Encrypt the string to an array of bytes.
string encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
// Decrypt the bytes to a string.
string roundtrip = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.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);
}
Console.ReadLine();
}
}
}
This is the problem (or at least a problem):
return System.Text.Encoding.UTF8.GetString(encrypted);
The encrypted data isn't UTF-8 text. It's arbitrary binary data. Don't treat it as if it were encoded text.
If you really need to pass arbitrary binary data around as a string, use Base64:
return Convert.ToBase64String(encrypted);
Then in DecryptStringFromBytes, you'd use:
byte[] cipherText = Convert.FromBase64String(codedText);
(Parameter name changed to comply with conventions.)