C# - pgp_sym_decrypt? - c#

I have a PostgreSQL database where I use the pgp_sym_encrypt() function to crypt data
INSERT INTO public.product(name, brand, size, price)
VALUES (pgp_sym_encrypt('product1', 'AES_KEY'), 'brand 1', 1, 1);
And it works with pgp_sym_decrypt()
SELECT pgp_sym_decrypt(name::bytea, 'AES_KEY') FROM public.product;
Is there some equivalent code in c# to decrypt the data which are crypted with the pgp_sym_encrypt() function ?
I tried this kind of code but I always get the crypted data
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes("AES_KEY");
aes.IV = new byte[16];
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
var buffer = Encoding.UTF8.GetBytes(data);
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}

Related

Why file is broken when used AES to decrypt?

i have encrypt/decrypt code for encryption file.
i used succeed with RijndaelManaged but when changed to used AES decrypted file is broken
code used to decrypt file :
using (AesManaged aes = new AesManaged())
{
byte[] iv = new byte[16];
aes.Key = Encoding.UTF8.GetBytes(skey);
aes.IV = iv;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
{
using (FileStream fsOut = new FileStream(outputFile, FileMode.Create))
{
using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
using (CryptoStream cs = new CryptoStream(fsCrypt, decryptor, CryptoStreamMode.Read))
{
int data;
while ((data = cs.ReadByte()) != -1)
{
fsOut.WriteByte((byte)data);
}
}
}
}
}
}

C# decrypt AES from byte[] not complete input data

I am trying to decrypt a byte[] the length of 30601 with the following method
public static byte[] DecryptObject(byte[] recObj, byte[] aesKey, byte[] aesIV) {
using (Aes aes = Aes.Create()) {
aes.BlockSize = 128;
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.PKCS7;
aes.Key = aesKey;
aes.IV = aesIV;
using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV)) {
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write)) {
cs.Write(recObj, 0, recObj.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
}
}
}
I have confirmed the key and iv is the same in which I used to encrypt with, but its throwing the error on cs.FlushFinalBlock(); with error
System.Security.Cryptography.CryptographicException: 'The input data is not a complete block.'
I have tried other methods to get this resolved but they are not working.
I am using this to encrypt
public static byte[] EncryptAes(byte[] data, byte[] key, byte[] iv) {
using (var aes = Aes.Create()) {
aes.Padding = PaddingMode.PKCS7;
aes.Key = key;
aes.IV = iv;
using (var ms = new MemoryStream()) {
using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) {
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
}
}
}

Encrypting and Decrypting a file with AES generates a broken file

I'm trying to encrypt and decrypt a file using AES. The problem that I have is that when the file gets decrypted, it is broken and you can't open it. The original file has a length of 81.970 bytes and the decrypted file has a length of 81.984 bytes...so there are 14 bytes added for some reason. The problem could be in the way the file gets encrypted but I don't know what I'm doing wrong.
What am I missing here? Could it be the way I'm processing the password, the iv and the padding?
Thanks for your time!
This is the code I use to encrypt:
private AesManaged aesManaged;
private string filePathToEncrypt;
public Encrypt(AesManaged aesManaged, string filePathToEncrypt)
{
this.aesManaged = aesManaged;
this.filePathToEncrypt = filePathToEncrypt;
}
public void DoEncryption()
{
byte[] cipherTextBytes;
byte[] textBytes = File.ReadAllBytes(this.filePathToEncrypt);
using(ICryptoTransform encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV))
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(textBytes, 0, textBytes.Length);
cs.FlushFinalBlock();
cipherTextBytes = ms.ToArray();
}
File.WriteAllBytes("EncryptedFile.aes", cipherTextBytes);
}
This is the code I use to decrypt:
private AesManaged aesManaged;
private string filePathToDecrypt;
public Decrypt(AesManaged aesManaged, string filePathToDecrypt)
{
this.aesManaged = aesManaged;
this.filePathToDecrypt = filePathToDecrypt;
}
public void DoDecrypt()
{
byte[] cypherBytes = File.ReadAllBytes(this.filePathToDecrypt);
byte[] clearBytes = new byte[cypherBytes.Length];
ICryptoTransform encryptor = aesManaged.CreateDecryptor(aesManaged.Key, aesManaged.IV);
using (MemoryStream ms = new MemoryStream(cypherBytes))
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Read))
{
cs.Read(clearBytes, 0, clearBytes.Length);
clearBytes = ms.ToArray();
}
File.WriteAllBytes("DecryptedFile.gif", clearBytes);
}
And here is how I call the functions:
string filePathToEncrypt = "dilbert.gif";
string filePathToDecrypt = "EncryptedFile.aes";
string password = "Password";
string passwordSalt = "PasswordSalt";
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(passwordSalt));
var aesManaged = new AesManaged
{
Key = deriveBytes.GetBytes(128 / 8),
IV = deriveBytes.GetBytes(16),
Padding = PaddingMode.PKCS7
};
Console.WriteLine("Encrypting File...");
var encryptor = new Encrypt(aesManaged, filePathToEncrypt);
encryptor.DoEncryption();
Thread.Sleep(300);
Console.WriteLine("Decrypting File...");
var decryptor = new Decrypt(aesManaged, filePathToDecrypt);
decryptor.DoDecrypt();
Thread.Sleep(300);
Try with:
public void DoEncryption()
{
byte[] cipherBytes;
byte[] textBytes = File.ReadAllBytes(this.filePathToEncrypt);
using (ICryptoTransform encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV))
using (MemoryStream input = new MemoryStream(textBytes))
using (MemoryStream output = new MemoryStream())
using (CryptoStream cs = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
{
input.CopyTo(cs);
cs.FlushFinalBlock();
cipherBytes = output.ToArray();
}
File.WriteAllBytes("EncryptedFile.aes", cipherBytes);
}
and
public void DoDecrypt()
{
byte[] cypherBytes = File.ReadAllBytes(this.filePathToDecrypt);
byte[] textBytes;
using (ICryptoTransform decryptor = aesManaged.CreateDecryptor(aesManaged.Key, aesManaged.IV))
using (MemoryStream input = new MemoryStream(cypherBytes))
using (MemoryStream output = new MemoryStream())
using (CryptoStream cs = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
{
cs.CopyTo(output);
textBytes = output.ToArray();
}
File.WriteAllBytes("DecryptedFile.gif", textBytes);
}
Note that the code could be modified to not use temporary byte[] and read/write directly to input/output streams.
In general you can't desume the length of the plaintext from the length of the cyphertext, so this line:
new byte[cypherBytes.Length]
was totally wrong.
And please, don't use Encoding.ASCII in 2016. It is so like previous century. Use Encoding.UTF8 to support non-english characters.
The answer may be very simple. I don't see where do u try to choose a cipher mode, so by default it probably takes CBC, as IV was inited. Then, 81.970 are padded by 14 bytes, to be divisible by 32. So when it happens, the memory you allocated was just 81.970, so the padding bytes doesn't write correctly, cause of some sort of memory leak, and when decrypt is started, unpadding doesn't work correctly.

Reading from a CryptoStream results in a padding error

I'm writing an Aes decryption method and currently, I'm stuck on trying to read all the contents inside my CryptoStream and put it all into a byte[]. This is what I have for decryption:
public byte[] GetDecrypted()
{
byte[] toReturn;
using (Aes dec = Aes.Create())
{
dec.Key = Key;
dec.IV = IV;
ICryptoTransform cryptoTransform = dec.CreateDecryptor(dec.Key, dec.IV);
using (MemoryStream ms = new MemoryStream(Data))
{
using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read))
{
using (MemoryStream decMs = new MemoryStream())
{
cs.CopyTo(decMs);
toReturn = decMs.ToArray();
}
}
}
}
return toReturn;
}
For encryption, I used very similar code; maybe something's wrong here:
public byte[] GetEncrypted()
{
byte[] toReturn;
using (Aes enc = Aes.Create())
{
enc.Key = Key;
enc.GenerateIV();
IV = enc.IV;
ICryptoTransform cryptoTransform = enc.CreateEncryptor(enc.Key, enc.IV);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
{
cs.Write(Data, 0, Data.Length);
toReturn = ms.ToArray();
}
}
}
return toReturn;
}
Your problem indeed lies in your encrypt side. You must close the crypto stream to flush the data out to the underlying stream first. It is a easy fix, just move your .ToArray() outside of CryptoStream's using block.
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
{
cs.Write(Data, 0, Data.Length);
}
toReturn = ms.ToArray();
}

AeS encryption 'Value cannot be null'

I have recently been experimenting with the "CryptoStream", and ran into the idea of encrypting & decrypting a text via. the Aes class. 'Namespace: System.Security.Cryptography'
After making a function that succesfully encrypted a text using two input parameters: Text, Password
static byte[] Salt = { 18,39,27,48,82,32,12,92 };
public static string EncryptAES(string txt, string Password) {
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(Password, Salt);
RijndaelManaged RJM = new RijndaelManaged();
RJM.Key = rfc.GetBytes(RJM.KeySize / 8);
ICryptoTransform ICT = Aes.Create().CreateEncryptor(RJM.Key, RJM.IV);
using (MemoryStream MS = new MemoryStream()) {
using (CryptoStream CS = new CryptoStream(MS, ICT, CryptoStreamMode.Write)) {
using (StreamWriter SW = new StreamWriter(CS)) {
SW.Write(txt);
}
}
return Convert.ToBase64String(MS.ToArray());
}
}
The issue of decrypting the text took place.
My attempt of decrypt the text was the following:
public static string DecryptAES(string EncryptedTxt, string Password) {
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(EncryptedTxt, Salt);
RijndaelManaged RJM = new RijndaelManaged();
RJM.Key = rfc.GetBytes(RJM.KeySize / 8);
ICryptoTransform ICT = Aes.Create().CreateDecryptor(RJM.Key, RJM.IV);
using (MemoryStream MS = new MemoryStream(Convert.FromBase64String(EncryptedTxt))) {
using (CryptoStream CS = new CryptoStream(MS, ICT, CryptoStreamMode.Read)) {
using (StreamReader SR = new StreamReader(CS)) {
return SR.ReadToEnd();
}
}
}
However; it appears that my way of converting the memorystream to string and then back was invaild, as I get the following error: Error: Value cannot be null\nParameter name: inputBuffer
The error occurs at using (MemoryStream MS = new MemoryStream(Convert.FromBase64String(EncryptedTxt)))
How can I converter the MemoryStream into string and back?
Thanks in advance :-)

Categories

Resources