I'm getting the infamous "Padding is invalid and cannot be removed." error. However, despite ensuring the padding mode is set as well as verifying the key is the same on both encrypt and decrypt. I can't get past the issue.
What am I doing wrong o' great sages of the internet?
//Targeting .Net 4.5.2
//Key is hard coded, ONLY while working through this error in a minimum repo.
byte[] testKey = Convert.FromBase64String("KN1df3fOkLmSPyOP4r+grlVFDC/JVlWuew1u/hDGvUU=");
//Called to Encrypt ("D:\\Assets\\", "Test.txt")
public void DoWork(string filePath, string fileName){
CryptographyUtil crypto = new CryptographyUtil(testKey);
crypto.EncryptFile(filePath, fileName));
}
//Called to Decrypt ("D:\\Assets\\", "Test.txt.dat")
public void UnDoWork(string filePath, string fileName){
CryptographyUtil crypto = new CryptographyUtil(testKey);
crypto.DecryptFile(filePath, fileName));
}
public class CryptographyUtil(){
RijndaelManaged rjndl;
RNGCryptoServiceProvider cRng;
public CryptographyUtil(byte[] key, int keySize = 256, int blockSize = 256) {
cRng = new RNGCryptoServiceProvider();
rjndl = new RijndaelManaged();
rjndl.Key = key;
rjndl.KeySize = keySize;
rjndl.BlockSize = blockSize;
rjndl.Mode = CipherMode.CBC;
rjndl.Padding = PaddingMode.PKCS7;
}
public void EncryptFile(string filePath, string fileName) {
string inputFilePath = Path.Combine(filePath, fileName);
if(!File.Exists(inputFilePath)) {
throw new FileLoadException("Unable to locate or open file.", inputFilePath);
}
string outputDirectory = Path.Combine(filePath, "Encrypted");
if(!Directory.Exists(outputDirectory)){
Directory.CreateDirectory(outputDirectory);
}
string outputPath = Path.Combine(outputDirectory, fileName + ".dat");
//Create a unique IV each time
byte[] iv = new byte[rjndl.BlockSize / 8]
cRng.GetBytes(iv);
byte[] ivSize = BitConverter.GetBytes(iv.Length);
ICryptoTransform encryptor = rjndl.CreateEncryptor(rjndl.Key, iv);
using(FileStream readStream = File.OpenRead(inputFilePath)) {
using(FileStream writeStream = new FileStream(outputPath, FileMode.Create)) {
using(CryptoStream encryptStream = new CryptoStream(writeStream, encryptor, CryptoStreamMode.Write)) {
//Write the following to the file before the encrypted data:
// - length of the IV
// - the IV
writeStream.Write(ivSize, 0, ivSize.Length);
writeStream.Write(iv, 0, iv.Length);
readStream.CopyTo(encryptStream);
readStream.Flush();
encryptStream.FlushFinalBlock();
encryptStream.Close();
}
writeStream.Close();
}
readStream.Close();
}
}
public void DecryptFile(string filePath, string fileName) {
string outputDirectory = Path.Combine(filePath, "Decrypted");
if(!Directory.Exists(outputDirectory)){
Directory.CreateDirectory(outputDirectory);
}
//Remove the ".dat" from the end of the file
string outputFilePath = Path.Combine(outputDirectory, fileName.Substring(0, fileName.LastIndexOf('.')));
if(File.Exists(outputFilePath)){
File.Delete(outputFilePath);
}
using(FileStream readStream = File.OpenRead(Path.Combine(filePath, fileName))) {
//Size buffer for IV Length (int = 4 bytes)
byte[] buffer = new byte[4];
readStream.Read(buffer, 0, buffer.Length);
int ivLength = BitConverter.ToUInt16(buffer, 0);
//Re-size buffer for IV
buffer = new byte[ivLength];
//Read IV to buffer and use to create decryptor
readStream.Read(buffer, 0, ivLength);
//Use IV in buffer to create decryptor
ICryptoTransform decryptor = rjndl.CreateDecryptor(rjndl.Key, buffer);
buffer = new byte[1024];
using(FileStream writeStream = new FileStream(outputFilePath, FileMode.Create)) {
using(CryptoStream decryptStream = new CryptoStream(readStream, decryptor, CryptoStreamMode.Read)) {
//FIXME: Padding Error
int readIdx = decryptStream.Read(buffer, 0, buffer.Length);
while(readIdx > 0) {
writeStream.Write(buffer, 0, readIdx);
readIdx = decryptStream.Read(buffer, 0, buffer.Length);
}
decryptStream.Flush();
decryptStream.Close();
}
writeStream.Close();
}
readStream.Close();
}
}
}
Using RijndaelManaged as I have to create encrypted packages for legacy software that uses it to decrypt.
Related
Need help T_T
I'm running the code below to Decrypt an exe File I'm trying to Run it and Automatically execute the Decrypted file would it be possible to execute it without saving it's data to the disk?
I'm also trying to run it without the need of specifying the encrypted file name but have no idea what changes need to be done for this to happen or if it's even possible.
FileInfo encFile = new FileInfo("7GNTBBASDADASDASDASDASDASDASDASDSW7VBKGUX5TB5XBXDG3W4DWC6K6JBMTG7C2OYEHNPSN4PE6JYLJDUA"); // < File name in the current directory
const int ReadBufferSize = 64 * 1024;
static void Main(string[] args)
{
{
// DECRYPTION
FileInfo encFile = new FileInfo("7GNTBBASDADASDASDASDASDASDASDASDSW7VBKGUX5TB5XBXDG3W4DWC6K6JBMTG7C2OYEHNPSN4PE6JYLJDUA"); // < File name in the current directory
byte[] iv = Convert.FromBase64String("SWW/HAWEWQF/F2d/WrSSA==");
byte[] key = Convert.FromBase64String("ASDSADSAwwqIM221vASXG1221nqk=");
// DECRYPTION
// DECRYPTION
using (FileStream inp = encFile.OpenRead())
using (AesManaged aes = new AesManaged())
{
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.IV = iv;
aes.Key = key;
using (CryptoStream cs = new CryptoStream(inp, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
// crypted file structure: {name length x4}{full file name}{data length x8}{data}{sha512 hash of data x64}
byte[] nameLengthBits = new byte[2];
if (cs.Read(nameLengthBits, 0, 2) != 2)
{
Console.Error.WriteLine("ERROR: Failed reading file name size");
return;
}
ushort nameLength = BitConverter.ToUInt16(nameLengthBits, 0);
byte[] originalName = new byte[nameLength];
if (cs.Read(originalName, 0, nameLength) != nameLength)
{
Console.Error.WriteLine("ERROR: Failed reading file name");
return;
}
string fileName = Encoding.UTF8.GetString(originalName);
byte[] dataLengthBits = new byte[8];
if (cs.Read(dataLengthBits, 0, dataLengthBits.Length) != dataLengthBits.Length)
{
Console.Error.WriteLine("ERROR: Failed reading data length");
return;
}
long dataLength = BitConverter.ToInt64(dataLengthBits, 0);
string outputFileName = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(fileName));
if (File.Exists(outputFileName))
{
}
byte[] decryptedHash;
long totalRead = 0;
using (FileStream outputStream = new FileStream(outputFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
using (SHA512Managed hasher = new SHA512Managed())
{
byte[] buffer = new byte[ReadBufferSize];
long bytesRemaining = dataLength;
while (bytesRemaining > 0)
{
int readingThisRound = ReadBufferSize < bytesRemaining ? ReadBufferSize : (int)bytesRemaining;
int bytesRead = cs.Read(buffer, 0, readingThisRound);
totalRead += bytesRead;
// dump decrypted data to file
outputStream.Write(buffer, 0, bytesRead); }
//
//
hasher.TransformFinalBlock(buffer, 0, 0);
decryptedHash = hasher.Hash;}
byte[] originalHashBits = new byte[64];
if (cs.Read(originalHashBits, 0, originalHashBits.Length) != originalHashBits.Length) using (FileStream outputStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
}
if (originalHashBits.SequenceEqual(decryptedHash))
I have an Encrypted string and function to decrypt it. Now I need to edit this string and encrypt it. When I use this function to encrypt and decrypt in result strings are not the same.
Orginal encrypted string:
APpuC6G3f3cUKaAuOFXOGIo9rwz/+fQ0tBCi6Fk40THVnIT+au7JXkOQHdgPcpQ3VUrXw69rIL+QRsHea5+Q6TxOeuAnzkU8c3UClx6Toe+jOIVi3DlkLIGzE8DmyBArtZYpKTOt4rrOSDyLKifdgcM+MgwuJbDXyXVuQyp2C42zZ1ETPUOF2TSIZKhnMSR43FFy8WEbpKBAjkPmgVpqqhrjabu+JHbj7kPIxGGjDHGaCCyCtFwsk3264Lv4GTp049SCjNNYV0NVcN4wV0MaWMEO0iLuNGkseHuu5Snvp3YzZfXxDBWSLOUXc2zeXL2tA6So9WA5P3lZ/ga5i366EQ==
Orginal encrypted string after decrypt:
{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":9999999999},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
Orginal decrypt function:
public static string Decypher(string var1)
{
var1 = var1.Trim();
byte[] array = Convert.FromBase64String(var1);
byte[] array2 = new byte[16];
byte[] array3 = new byte[32];
byte[] array4 = new byte[array.Length - 48];
for (int i = 0; i < 16; i++)
{
array2[i] = array[i];
}
for (int j = 16; j < 48; j++)
{
array3[j - 16] = array[j];
}
for (int k = 48; k < array.Length; k++)
{
array4[k - 48] = array[k];
}
ivv = array2;
Aes aes = Aes.Create();
aes.Mode = CipherMode.CBC;
aes.Key = GetToken();
aes.IV = array2;
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform transform = aes.CreateDecryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
string result = string.Empty;
try
{
cryptoStream.Write(array4, 0, array4.Length);
cryptoStream.FlushFinalBlock();
byte[] array5 = memoryStream.ToArray();
result = Encoding.ASCII.GetString(array5, 0, array5.Length);
memoryStream.Close();
cryptoStream.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace);
}
return result;
}
My encrypt function:
public void EncryptStringToBytes()
{
string plainText = textBox2.Text;
byte[] array = Encoding.UTF8.GetBytes(plainText);
byte[] encrypted;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = GetToken();
aesAlg.IV = new byte[16];
aesAlg.Mode = CipherMode.CBC;
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
textBox3.Text = Convert.ToBase64String(encrypted);
}
String after my encrypt & decrypt with orginal function:
?%j>]???r?????":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
EDIT:
Now encrypt function look:
public void EncryptStringToBytes()
{
string plainText = textBox2.Text.Trim();
byte[] array = Encoding.ASCII.GetBytes(plainText);
byte[] encrypted;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = GetToken();
aesAlg.IV = GetIV();
aesAlg.Mode = CipherMode.CBC;
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (var msEncrypt = new MemoryStream())
{
msEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
msEncrypt.Flush();
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
textBox3.Text = Convert.ToBase64String(encrypted);
}
But string after encrypt & decrypt look:
;???En Dp??g???{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
My C# AES implementation
from my answer AES Crypto C# compatible Java
The IV is randomized in every Encrypt process to get different output with same text and avoid to intruders/attackers get original text easily.
The default mode is CBC.
The encoding used is UTF-8. UTF-8 is the most widely used encoding on the web.
You can test/run this code on https://replit.com/#JomaCorpFX/AesCbcEncrypt#main.cs
The code
using System;
using System.Security.Cryptography;
using System.Text;
public enum HashAlgorithm
{
MD5,
SHA1,
SHA256,
SHA384,
SHA512
}
public class HashManager
{
public static byte[] ToRawHash(byte[] data, HashAlgorithm algorithm)
{
byte[] hash;
switch (algorithm)
{
case HashAlgorithm.MD5:
MD5 md5 = MD5.Create();
hash = md5.ComputeHash(data, 0, data.Length);
return hash;
case HashAlgorithm.SHA1:
SHA1Managed sha1 = new SHA1Managed();
hash = sha1.ComputeHash(data);
return hash;
case HashAlgorithm.SHA256:
SHA256Managed sha256 = new SHA256Managed();
hash = sha256.ComputeHash(data);
return hash;
case HashAlgorithm.SHA384:
SHA384Managed sha384 = new SHA384Managed();
hash = sha384.ComputeHash(data);
return hash;
case HashAlgorithm.SHA512:
SHA512Managed sha512 = new SHA512Managed();
hash = sha512.ComputeHash(data, 0, data.Length);
return hash;
default:
throw new ArgumentException("Invalid Algorithm");
}
}
}
public class AesManager
{
private const int MAX_IV_LENGTH = 16;
private const int MAX_KEY_LENGTH = 32;
private static byte[] GenerateValidKey(byte[] keyBytes)
{
byte[] ret = new byte[MAX_KEY_LENGTH];
byte[] hash = HashManager.ToRawHash(keyBytes, HashAlgorithm.SHA256);
Array.Copy(hash, ret, MAX_KEY_LENGTH);
return ret;
}
public static byte[] EncryptRaw(byte[] PlainBytes, byte[] Key)
{
AesManaged AesAlgorithm = new AesManaged()
{
Key = GenerateValidKey(Key)
};
AesAlgorithm.GenerateIV();
var Encrypted = AesAlgorithm.CreateEncryptor().TransformFinalBlock(PlainBytes, 0, PlainBytes.Length);
byte[] ret = new byte[Encrypted.Length + MAX_IV_LENGTH];
Array.Copy(Encrypted, ret, Encrypted.Length);
Array.Copy(AesAlgorithm.IV, 0, ret, ret.Length - MAX_IV_LENGTH, MAX_IV_LENGTH);
return ret;
}
public static byte[] DecryptRaw(byte[] CipherBytes, byte[] Key)
{
AesManaged AesAlgorithm = new AesManaged()
{
Key = GenerateValidKey(Key)
};
byte[] IV = new byte[MAX_IV_LENGTH];
Array.Copy(CipherBytes, CipherBytes.Length - MAX_IV_LENGTH, IV, 0, MAX_IV_LENGTH);
AesAlgorithm.IV = IV;
byte[] RealBytes = new byte[CipherBytes.Length - MAX_IV_LENGTH];
Array.Copy(CipherBytes, RealBytes, CipherBytes.Length - MAX_IV_LENGTH);
return AesAlgorithm.CreateDecryptor().TransformFinalBlock(RealBytes, 0, RealBytes.Length); ;
}
public static String EncryptToBase64(String Plaintext, String Key)
{
byte[] PlainBytes = Encoding.UTF8.GetBytes(Plaintext);
return Base64Manager.ToBase64(EncryptRaw(PlainBytes, Encoding.UTF8.GetBytes(Key)), false);
}
public static String DecryptFromBase64(String CipherText, String Key)
{
byte[] CiPherBytes = Base64Manager.Base64ToByteArray(CipherText);
byte[] Encrypted = DecryptRaw(CiPherBytes, Encoding.UTF8.GetBytes(Key));
return Encoding.UTF8.GetString(Encrypted, 0, Encrypted.Length);
}
}
public class Base64Manager
{
public static byte[] Base64ToByteArray(String base64)
{
return Convert.FromBase64String(base64);
}
public static String ToBase64(byte[] data, Boolean insertLineBreaks = default(Boolean))
{
return insertLineBreaks ? Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks) : Convert.ToBase64String(data);
}
}
public class Program
{
public static void Main()
{
Console.Write("Plain text: ");
string plainText = Console.ReadLine();
Console.Write("Password: ");
string password = Console.ReadLine();
string encrypted = AesManager.EncryptToBase64(plainText, password);
Console.WriteLine();
Console.WriteLine($"Password: {password}" );
Console.WriteLine();
Console.WriteLine($"Encrypted: {encrypted}");
Console.WriteLine();
Console.WriteLine($"Decrypted: {AesManager.DecryptFromBase64(encrypted, password)}");
Console.ReadLine();
}
}
Output
I created public and private keys (pem) with openSsl tool. I used commands:
openssl genrsa -out privatekey.pem 2048
openssl req -new -key privatekey.pem -x509 -days 3650 -out publiccert.pem
Then I generate aesKey:
byte[] GenerateAesKey()
{
var rnd = new RNGCryptoServiceProvider();
var b = new byte[16];
rnd.GetNonZeroBytes(b);
return b;
}
My method for encrypt data:
string CreateSecurePayload(byte[] aesKey)
{
object obj = new
{
contact = new
{
email = "myName#email.com",
firstName = "John",
lastName = "Doe"
}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var res = "";
using (Aes myRijndael = Aes.Create())
{
byte[] encrypted = EncryptStringToBytes(json, aesKey, myRijndael.IV);
res = Convert.ToBase64String(encrypted);
}
return res;
}
byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
using (Aes rijAlg = Aes.Create())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
And then I encrypt my aesKey with private key:
string SecureKey(byte[] aesKey)
{
byte[] plainTextBytes = aesKey;
AsymmetricCipherKeyPair keys;
FileStream fileStream = new FileStream("path/to/privatekey.pem", FileMode.Open);
using (var reader = new StreamReader(fileStream))
{
var pr = new PemReader(reader);
keys = (AsymmetricCipherKeyPair)pr.ReadObject();
}
var eng = new OaepEncoding(new RsaEngine());
eng.Init(true, keys.Private);
int length = plainTextBytes.Length;
int blockSize = eng.GetInputBlockSize();
var cipherTextBytes = new List<byte>();
for (int chunkPosition = 0;
chunkPosition < length;
chunkPosition += blockSize)
{
int chunkSize = Math.Min(blockSize, length - chunkPosition);
cipherTextBytes.AddRange(eng.ProcessBlock(
plainTextBytes, chunkPosition, chunkSize
));
}
return Convert.ToBase64String(cipherTextBytes.ToArray());
}
Call methods:
void Main()
{
var aesKey = GenerateAesKey();
var encryptData = Newtonsoft.Json.JsonConvert.SerializeObject(new
{
securePayload = CreateSecurePayload(aesKey),
secureKey = SecureKey(aesKey)
});
}
I have a problem. Service does not decrypt my data with public key. I upload public key earlier in service.
Could you help me? Thanks
And I have examples of how I can encrypt data but in other languages:
I got the example, but on JS. I think I have a problem with IV, because I don`t send it
Here is the class that help you to perform Encryption/Decryption:
public static class DecryptionHelper
{
private static string EncryptionDecryptionKey = "your_key";
public static string Encrypt(string Text)
{
//var key = GenerateKey();
var key = Encoding.UTF8.GetBytes(EncryptionDecryptionKey);
var plainText = Text;
var encryptedData = EncryptStringToBytes(key, plainText);
return Convert.ToBase64String(encryptedData);
}
public static string Decrypt(string Text)
{
//var key = GenerateKey();
var key = Encoding.UTF8.GetBytes(EncryptionDecryptionKey);
byte[] encryptedData = Convert.FromBase64String(Text);
var decryptedData = DecryptBytesToString(key, encryptedData);
return decryptedData;
}
private static string DecryptBytesToString(byte[] key, byte[] data)
{
// IV was prepended to the encrypted bytes so peel that off
Tuple<byte[], byte[]> splitResult = SplitByteArray(data);
byte[] iv = splitResult.Item1;
byte[] cipherText = splitResult.Item2;
// Declare the string used to hold the decrypted text.
string plaintext;
// Create an RijndaelManaged object
// with the specified key and IV.
using (var aes = CreateAes256Algorithm())
{
aes.Key = key;
aes.IV = iv;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.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;
}
private static Tuple<byte[], byte[]> SplitByteArray(byte[] data)
{
byte[] first = new byte[16];
Buffer.BlockCopy(data, 0, first, 0, first.Length);
byte[] second = new byte[data.Length - first.Length];
Buffer.BlockCopy(data, first.Length, second, 0, second.Length);
return Tuple.Create(first, second);
}
private static byte[] GenerateKey()
{
using (var aes = CreateAes256Algorithm())
{
aes.GenerateKey();
return aes.Key;
}
}
private static RijndaelManaged CreateAes256Algorithm()
{
return new RijndaelManaged { KeySize = 256, BlockSize = 128 };
}
private static byte[] EncryptStringToBytes(byte[] key, string plainText)
{
byte[] encrypted;
byte[] iv;
// Create an RijndaelManaged object with the specified key and IV.
using (var aes = CreateAes256Algorithm())
{
aes.Key = key;
aes.GenerateIV();
iv = aes.IV;
// Create a encrytor to perform the stream transform.
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.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);
}
// convert stream to bytes
encrypted = msEncrypt.ToArray();
}
}
}
// Prepend the iV to the encrypted bytes
return CombineByteArrays(iv, encrypted);
}
private static byte[] CombineByteArrays(byte[] first, byte[] second)
{
byte[] ret = new byte[first.Length + second.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
return ret;
}
}
Then to use it like:
Keys.FacebookClientId = DecryptionHelper.Decrypt(FacebookClientId);
using System;
using System.Text;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using System.Security.Cryptography;
using System.IO;
public static string CreateSecureLoad(string unencryptedPayload, ref byte[] generatedAesKey)
{
// This method generates and returns a secure payload
RijndaelManaged cryptoAlgo = new RijndaelManaged
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.ECB,
KeySize = 128,
BlockSize = 128
};
generatedAesKey = cryptoAlgo.Key;
var clearTextArray = Encoding.UTF8.GetBytes(unencryptedPayload);
var encryptor = cryptoAlgo.CreateEncryptor();
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(
msEncrypt,
encryptor,
CryptoStreamMode.Write))
{
csEncrypt.Write(clearTextArray);
csEncrypt.FlushFinalBlock();
var cipher = msEncrypt.ToArray();
return Convert.ToBase64String(cipher);
}
}
}
public static string CreateSecureKey(byte[] aesKey, string privateKeyPEM)
{
// This method generates and returns a secure key
// Accepts the string contents of the private key PEM file as input
var encryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var textReader = new StringReader(privateKeyPEM))
{
var pemReader = new PemReader(textReader);
var keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
encryptEngine.Init(true, keyPair.Private);
}
var encrypted = Convert.ToBase64String(
encryptEngine.ProcessBlock(
aesKey,
0,
aesKey.Length));
return encrypted;
}
static void Main(string[] args)
{
String payload = "some json";
byte[] generatedAesKey = new byte[16];
var privateKeyPEM = File.ReadAllText("privatekey.pem");
var securePayload = CreateSecureLoad(payload, ref generatedAesKey);
var secureKey = CreateSecureKey(generatedAesKey, privateKeyPEM);
// Return encrypted key
Console.WriteLine("secureKey: " + secureKey);
// Return encrypted payload
Console.WriteLine("securePayload: " + securePayload);
Console.ReadLine();
}
}
I am developing an image encrypting program. I have got two applications. One of them, converting image to byte array and encrypting with Rijndael. After it is saving encrypted byte array to a file. Second application is for decrypting. I am reading byte array from file. After i am decrypt and show image in picturebox.
But i am geting "Padding is invalid and cannot be removed." error in decryption application.
Now i am saving encrypted byte array to a file this code (I am not sure is it true way for byte array to file ?);
protected bool SaveData(string FileName, byte[] Data)
{
BinaryWriter Writer = null;
try
{
// Create a new stream to write to the file
Writer = new BinaryWriter(File.Open(FileName,FileMode.OpenOrCreate));
// Writer raw data
Writer.Write(Data);
Writer.Flush();
Writer.Close();
}
catch
{
return false;
}
return true;
}
I am giving this method save file location and encrypted byte array. And It is worked. But i dont know, is it correct way ?
And my decryption application reading encrypted byte array from file method;
protected byte[] GetData(string FileName)
{
FileInfo f = new FileInfo(FileName);
BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open));
byte[] a = br.ReadBytes(Convert.ToInt32(f.Length));
return a;
}
And Error location decryption method;
public static byte[] DecryptBytes(byte[] encryptedBytes, string passPhrase, string saltValue)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
RijndaelCipher.Mode = CipherMode.CBC;
byte[] salt = Encoding.ASCII.GetBytes(saltValue);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));
MemoryStream memoryStream = new MemoryStream(encryptedBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
byte[] plainBytes = new byte[encryptedBytes.Length];
int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length); // I am getting error this line. Padding is invalid and cannot be removed.
memoryStream.Flush();
cryptoStream.Flush();
memoryStream.Close();
cryptoStream.Close();
return plainBytes;
}
Encryption Code
public static byte[] EncryptBytes(byte[] inputBytes, string passPhrase, string saltValue)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
RijndaelCipher.Mode = CipherMode.CBC;
byte[] salt = Encoding.ASCII.GetBytes(saltValue);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
cryptoStream.Write(inputBytes, 0, inputBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] CipherBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return CipherBytes;
}
Full Code Decryption Application
namespace ImageDecrypte
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string EncPass;
private string line;
private string OkunanVeri;
private byte[] SifreliDosyaDizi;
private byte[] CozulmusDosyaDizi;
private const string SaltPass = "CodeWork";
private string Sfre;
private string dyol;
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog file = new OpenFileDialog();
file.Filter = "Şifrelenmiş Dosyalar (*.cw)|*.cw";
file.FilterIndex = 2;
file.RestoreDirectory = true;
file.CheckFileExists = false;
file.Title = "Şifrelenmiş Dosya Seçiniz..";
file.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (file.ShowDialog() == DialogResult.OK)
{
dyol = file.FileName;
string DosyaAdi = file.SafeFileName;
label1.Text = DosyaAdi;
Sfre = textBox1.Text;
}
}
private void button2_Click(object sender, EventArgs e)
{
Sfre = textBox1.Text;
SifreliDosyaDizi = GetData(dyol);
CozulmusDosyaDizi = DecryptBytes(SifreliDosyaDizi, Sfre, SaltPass);
pictureBox1.Image = byteArrayToImage(CozulmusDosyaDizi);
}
public static byte[] DecryptBytes(byte[] encryptedBytes, string passPhrase, string saltValue)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
RijndaelCipher.Mode = CipherMode.CBC;
byte[] salt = Encoding.ASCII.GetBytes(saltValue);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));
MemoryStream memoryStream = new MemoryStream(encryptedBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
byte[] plainBytes = new byte[encryptedBytes.Length];
int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);
memoryStream.Flush();
cryptoStream.Flush();
memoryStream.Close();
cryptoStream.Close();
return plainBytes.Take(DecryptedCount).ToArray();
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
//File To Byte Array ###################################################################
protected byte[] GetData(string FileName)
{
FileInfo f = new FileInfo(FileName);
BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open));
byte[] a = br.ReadBytes(Convert.ToInt32(f.Length));
return a;
}
//File To Byte Array ###################################################################
}
}
Full Code Encryption Application
namespace ImageEncrypte
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string EncPass;
private byte[] byteArrayForImage;
private byte[] byteArrayCoded;
private const string SaltPass = "CodeWork";
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog file = new OpenFileDialog();
file.Filter = "Jpeg Dosyası |*.jpg| Png Dosyası|*.png";
file.FilterIndex = 2;
file.RestoreDirectory = true;
file.CheckFileExists = false;
file.Title = "Bir İmaj Dosyası Seçiniz..";
file.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
EncPass = textBox1.Text;
if (file.ShowDialog() == DialogResult.OK)
{
string DosyaYolu = file.FileName;
string DosyaAdi = file.SafeFileName;
label1.Text = DosyaAdi;
Image img = Image.FromFile(DosyaYolu);
pictureBox1.Image = img;
byteArrayForImage = imageToByteArray(img);
byteArrayCoded = EncryptBytes(byteArrayForImage, EncPass, SaltPass);
}
}
private void button2_Click(object sender, EventArgs e)
{
SaveFileDialog sf = new SaveFileDialog();
sf.Title = "Şifrelenmiş Dosyayı Kaydet";
sf.CheckFileExists = false;
sf.CheckPathExists = true;
sf.RestoreDirectory = true;
sf.DefaultExt = "cw";
sf.FileName = "EncodedFile";
sf.SupportMultiDottedExtensions = false;
sf.Filter = "Şifrelenmiş Dosyalar (*.cw)|*.cw";
sf.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
if (sf.ShowDialog() == DialogResult.OK)
{
string DosyaYolu = sf.FileName;
bool cevap = SaveData(DosyaYolu, byteArrayCoded);
if (cevap)
{
MessageBox.Show("OK");
}
else
{
MessageBox.Show("PROBLEM");
}
}
}
//Image To Byte Array ####################################################################
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
using (var ms = new MemoryStream())
{
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
}
//Image To Byte Array ####################################################################
//Byte Array To File ###################################################################
protected bool SaveData(string FileName, byte[] Data)
{
BinaryWriter Writer = null;
try
{
// Create a new stream to write to the file
Writer = new BinaryWriter(File.Open(FileName,FileMode.OpenOrCreate));
// Writer raw data
Writer.Write(Data);
Writer.Flush();
Writer.Close();
}
catch
{
return false;
}
return true;
}
//Bytte Array To File ###################################################################
//EncryptBytes ###################################################################
public static byte[] EncryptBytes(byte[] inputBytes, string passPhrase, string saltValue)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
RijndaelCipher.Mode = CipherMode.CBC;
byte[] salt = Encoding.ASCII.GetBytes(saltValue);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
cryptoStream.Write(inputBytes, 0, inputBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] CipherBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return CipherBytes;
}
//EncryptBytes ###################################################################
}
}
What can i do before going to be a crazy man ? Thank you and waiting your precious answers.
Thanks to Maximilian Gerhardt Solution is here;
public static byte[] EncryptBytes(byte[] inputBytes, string passPhrase, string saltValue)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
RijndaelCipher.Mode = CipherMode.CBC;
RijndaelCipher.Padding = PaddingMode.PKCS7;
byte[] salt = Encoding.UTF32.GetBytes(saltValue);
//byte[] salt = Encoding.ASCII.GetBytes(saltValue);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
cryptoStream.Write(inputBytes, 0, inputBytes.Length);
cryptoStream.FlushFinalBlock();
cryptoStream.Flush();
byte[] CipherBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return CipherBytes;
}
public static byte[] DecryptBytes(byte[] encryptedBytes, string passPhrase, string saltValue)
{
RijndaelManaged RijndaelCipher = new RijndaelManaged();
RijndaelCipher.Mode = CipherMode.CBC;
RijndaelCipher.Padding = PaddingMode.PKCS7;
byte[] salt = Encoding.UTF32.GetBytes(saltValue);
//byte[] salt = Encoding.ASCII.GetBytes(saltValue);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));
MemoryStream memoryStream = new MemoryStream(encryptedBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
byte[] plainBytes = new byte[encryptedBytes.Length];
int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);
memoryStream.Flush();
cryptoStream.Flush();
memoryStream.Close();
cryptoStream.Close();
return plainBytes.Take(DecryptedCount).ToArray();
}
public static byte[] GetData(string FileName)
{
return File.ReadAllBytes(FileName);
}
protected bool SaveData(string FileName, byte[] Data)
{
try
{
File.WriteAllBytes(FileName, Data);
return true;
}
catch
{
return false;
}
}
I use this function to decrypt a executable file :
public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) ...
But, this function return a string output I can see the ASCII output of my corresponding decrypted file. But, I need to get a byte[] output.
I have try many thing but I'm stuck: I need a DecryptBytesToBytes function
That function is proprietary - i.e. it's part of your codebase, it's certainly not part of the BCL. So I suggest you find the source code and write a new version that returns a byte array.
As a variant:
static byte[] DecryptBytesToBytes (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.
byte[] encrypted = 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))
{
string encrypted_text = srDecrypt.ReadToEnd();
encrypted = new byte[encrypted_text.Length * sizeof(char)];
System.Buffer.BlockCopy(encrypted_text.ToCharArray(), 0, encrypted, 0, encrypted.Length);
}
}
}
}
return encrypted;
}
The code you posted is for encrypting strings. The following code will encrypt a file and decrypt it using the file path. It will write out the file to the hard disk.
static void EncryptFile(string sInputFilename, string sOutputFilename, byte[] key, byte[] iv)
{
FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);
using (AesCryptoServiceProvider encryptor = new AesCryptoServiceProvider())
{
encryptor.Key = key;
encryptor.IV = iv;
ICryptoTransform transform = encryptor.CreateEncryptor();
using (CryptoStream cryptostream = new CryptoStream(fsEncrypted, transform, CryptoStreamMode.Write))
{
byte[] bytearrayinput = new byte[fsInput.Length];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
}
fsInput.Close();
fsEncrypted.Close();
}
}
static void DecryptFile(string sInputFilename, string sOutputFilename, byte[] key, byte[] iv)
{
using (AesCryptoServiceProvider encryptor = new AesCryptoServiceProvider())
{
encryptor.Key = key;
encryptor.IV = iv;
using (FileStream fsread = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read))
{
using (ICryptoTransform transform = encryptor.CreateDecryptor())
{
using (CryptoStream cryptostream = new CryptoStream(fsread, transform, CryptoStreamMode.Read))
{
using (BinaryWriter fsDecrypted = new BinaryWriter(File.Open(sOutputFilename, FileMode.Create)))
{
byte[] buffer = new byte[1024];
var read = cryptostream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
fsDecrypted.Write(buffer, 0, read);
read = cryptostream.Read(buffer, 0, buffer.Length);
}
fsDecrypted.Flush();
cryptostream.Flush();
}
}
}
}
}
}
This works without all the streams:
public static Byte[] Encrypt(Byte[] input, SymmetricAlgorithm crypto)
{
return Transform(crypto.CreateEncryptor(), input, crypto.BlockSize);
}
public static Byte[] Decrypt(Byte[] input, SymmetricAlgorithm crypto)
{
return Transform(crypto.CreateDecryptor(), input, crypto.BlockSize);
}
private static Byte[] Transform(ICryptoTransform cryptoTransform, Byte[] input, Int32 blockSize)
{
if (input.Length > blockSize)
{
Byte[] ret1 = new Byte[( ( input.Length - 1 ) / blockSize ) * blockSize];
Int32 inputPos = 0;
Int32 ret1Length = 0;
for (inputPos = 0; inputPos < input.Length - blockSize; inputPos += blockSize)
{
ret1Length += cryptoTransform.TransformBlock(input, inputPos, blockSize, ret1, ret1Length);
}
Byte[] ret2 = cryptoTransform.TransformFinalBlock(input, inputPos, input.Length - inputPos);
Byte[] ret = new Byte[ret1Length + ret2.Length];
Array.Copy(ret1, 0, ret, 0, ret1Length);
Array.Copy(ret2, 0, ret, ret1Length, ret2.Length);
return ret;
}
else
{
return cryptoTransform.TransformFinalBlock(input, 0, input.Length);
}
}