.net core PGP Encryption Decryption - c#

Running into error on the void Encryption().
public void Encryption()
{
#region PGP Encryption
PgpEncryptionKeys encryptionKeys = new PgpEncryptionKeys(#"C:\Keys\PGPPublicKey.asc", #"C:\Keys\PGPPrivateKey.asc", "password");
PgpEncrypt encrypter = new PgpEncrypt(encryptionKeys);
using (Stream outputStream = File.Create("C:\\Keys\\EncryptData.txt"))
{
encrypter.EncryptAndSign(outputStream, new FileInfo(#"D:\Keys\PlainText.txt"));
}
Console.WriteLine("Encryption Done !");
#endregion
}
I used https://code.msdn.microsoft.com/vstudio/Pretty-Good-Privacy-using-4f473c67
as a reference.
I am confused about the parameters in the PgpEncryptionKeys.
Does anyone have a working example or help? This is my first time encrypting so I am little lost.

I'm using by this way:
I think can help you!
Helper:
public static void EncryptPgpFile(string inputFile, string outputFile, string publicKeyFile, bool armor, bool withIntegrityCheck)
{
using (Stream publicKeyStream = File.OpenRead(publicKeyFile))
{
PgpPublicKey pubKey = ReadPublicKey(publicKeyStream);
using (MemoryStream outputBytes = new MemoryStream())
{
PgpCompressedDataGenerator dataCompressor = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
PgpUtilities.WriteFileToLiteralData(dataCompressor.Open(outputBytes), PgpLiteralData.Binary, new FileInfo(inputFile));
dataCompressor.Close();
PgpEncryptedDataGenerator dataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
dataGenerator.AddMethod(pubKey);
byte[] dataBytes = outputBytes.ToArray();
using (Stream outputStream = File.Create(outputFile))
{
if (armor)
{
using (ArmoredOutputStream armoredStream = new ArmoredOutputStream(outputStream))
using (Stream outputStream = dataGenerator.Open(armoredStream, dataBytes.Length))
outputStream.Write(dataBytes, 0, dataBytes.Length);
}
else
{
using (Stream outputStream = dataGenerator.Open(armoredStream, dataBytes.Length))
outputStream.Write(dataBytes, 0, dataBytes.Length);
}
}
}
}
}
private static PgpPublicKey ReadPublicKey(Stream inputStream)
{
inputStream = PgpUtilities.GetDecoderStream(inputStream);
PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(inputStream);
foreach (PgpPublicKeyRing keyRing in pgpPub.GetKeyRings())
{
foreach (PgpPublicKey key in keyRing.GetPublicKeys())
{
if (key.IsEncryptionKey)
return key;
}
}
throw new ArgumentException("Can't find encryption key in key ring.");
}
Usage:
EncryptPgpFile(inputFile, outputFile, publicKeyPath, true, true);

Related

How to compress a Byte array without stream or system io

I'm trying to encode an image into a byte array and send it to a server.
the encoding and sending parts wok fine but my problem is that the byte array is too large and takes too long to send so I thought compressing it would make it go faster. but the actual problem is that I CAN NOT use system.io or streams. and I'm targeting .net 2.0.
Thank you.
using System.IO;
using System.IO.Compression;
code:
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Optimal))
{
dstream.Write(data, 0, data.Length);
}
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream(data);
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
return output.ToArray();
}
Updated
Use 7zip library:
http://www.splinter.com.au/compressing-using-the-7zip-lzma-algorithm-in/
// Convert the text into bytes
byte[] DataBytes = ASCIIEncoding.ASCII.GetBytes(OriginalText);
// Compress it
byte[] Compressed = SevenZip.Compression.LZMA.SevenZipHelper.Compress(DataBytes);
// Decompress it
byte[] Decompressed = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(Compressed);
Compress
public static byte[] Compress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Optimal))
{
dstream.Write(inputData, 0, inputData.Length);
}
return output.ToArray();
}
OR
public static byte[] Compress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
using (var compressIntoMs = new MemoryStream())
{
using (var gzs = new BufferedStream(new GZipStream(compressIntoMs,
CompressionMode.Compress), BUFFER_SIZE))
{
gzs.Write(inputData, 0, inputData.Length);
}
return compressIntoMs.ToArray();
}
}
Decompress
public static byte[] Decompress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
MemoryStream input = new MemoryStream(inputData);
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
return output.ToArray();
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
}
OR
public static byte[] Decompress(byte[] inputData)
{
if (inputData == null)
throw new ArgumentNullException("inputData must be non-null");
using (var compressedMs = new MemoryStream(inputData))
{
using (var decompressedMs = new MemoryStream())
{
using (var gzs = new BufferedStream(new GZipStream(compressedMs, CompressionMode.Decompress), BUFFER_SIZE))
{
gzs.CopyTo(decompressedMs);
}
return decompressedMs.ToArray();
}
}
}

decompress by gzip failed

i'm write one pair function too compress and decompress but decompress failed
this is my code
public static byte[] CompressByGzip( byte[] input ) {
using(var ims = new MemoryStream()) {
using(var gzip = new GZipStream(ims, CompressionMode.Compress)) {
gzip.Write(input, 0, input.Length);
return ims.ToArray();
}
}
}
public static byte[] DecompressByGzip( byte[] input ) {
using(var ims = new MemoryStream()) {
using(var gzip = new GZipStream(ims, CompressionMode.Decompress)) {
using(var outms = new MemoryStream()) {
ims.Write(input, 0, input.Length);
byte[] buf = new byte[bufLength];
int len=0;
while((len=gzip.Read(buf, 0, buf.Length))>0) {
outms.Write(buf, 0, len);
}
return outms.ToArray();
}
}
}
}
when i debug,i found the gzip can't read,it has inner Exception....
Length = “gzip.Length”引发了“System.NotSupportedException”类型的异常
Your compressed output CompressByGzip is wrong. You need to flush the gzip stream before converting to array. Move the return ... statement.
public static byte[] CompressByGzip( byte[] input )
{
using(var ims = new MemoryStream())
{
using(var gzip = new GZipStream(ims, CompressionMode.Compress))
{
gzip.Write(input, 0, input.Length);
}
return ims.ToArray();
}
}
Here is what you can do for .Net 4.5
Compress
public static byte[] Compress(byte[] data, CompressionLevel level = CompressionLevel.Fastest)
{
using (var memory = new MemoryStream())
{
using (var gzip = new GZipStream(memory, level, true))
{
gzip.Write(data, 0, data.Length);
}
return memory.ToArray();
}
}
Decompress
public static byte[] Decompress(byte[] byteData)
{
if (byteData == null)
throw new ArgumentNullException("byteData", #"inputData must be non-null");
using (var compressedMs = new MemoryStream(byteData))
{
using (var decompressedMs = new MemoryStream())
{
using (var gzs = new BufferedStream(new GZipStream(compressedMs, CompressionMode.Decompress), 4096))
{
gzs.CopyTo(decompressedMs);
}
return decompressedMs.ToArray();
}
}
}

Encrypted Serialization of Objects in C#

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;
}
}

deserialization c#

I have a WPF application contains this class:*
{[Serializable]
public class Parametres
{
private string admin_login;
private string admin_pwd;
private string server;
private string db;
private string user;
private string pwd;}
i serialize an object with this function:
public static void Serialize_Parametres(string filename, Parametres obj)
{
using (FileStream fs = File.Open(filename, FileMode.OpenOrCreate))
{
using (CryptoStream cs = new CryptoStream(fs, key.CreateEncryptor(), CryptoStreamMode.Write))
{
XmlSerializer xmlser = new XmlSerializer(typeof(Parametres));
xmlser.Serialize(cs, obj);
}
}
}
it's works fine and it generates a file .txt , but when i try to deserialize this file and get the object parametres whith this function:
public static Parametres DeSerialize_Parametres(string filename)
{
using (FileStream fs = File.Open(filename, FileMode.Open))
{
using (CryptoStream cs = new CryptoStream(fs, key.CreateDecryptor(), CryptoStreamMode.Read))
{
XmlSerializer xmlser = new XmlSerializer(typeof(Parametres));
return (Parametres)xmlser.Deserialize(cs);
}
}
}
i got this error Length of the data to decrypt is invalid in the line return (Parametres)xmlser.Deserialize(cs);
What is exactly the reason of this error? how can i fix it?
When using this techique to serialize an object you have to do in two parts. The length encrypted stream must be stored as part of the final stream and its up to you to do this. However, you should break this up into a more resuable form.
For example, first serialze the graph you want into a byte stream; then
Encrypte the byte stream; then
Save it to a file.
Below is an example on how to Serialize to a file using AES:
public class ObjectXmlSerializer
{
//---------------------------------------------------------------------
public override Byte[] Serialize(Object obj)
{
using (MemoryStream ms = new MemoryStream())
{
new XmlSerializer(obj.GetType()).Serialize(ms, obj);
return ms.ToArray();
}
}
//---------------------------------------------------------------------
public override T Deserialize<T>(Byte[] bObj)
{
using (MemoryStream ms = new MemoryStream(bObj))
{
return (T)new XmlSerializer(typeof(T)).Deserialize(ms);
}
}
//---------------------------------------------------------------------
public override T Deserialize<T>(Stream iostream)
{
return (T)new XmlSerializer(typeof(T)).Deserialize(iostream);
}
}
// next
public static class CryptoSerivces
{
//---------------------------------------------------------------------
public static Byte[] AesEncrypt(Byte[] src, Byte[] key, Byte[] IV)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
try
{
myRijndael.Mode = CipherMode.CBC;
myRijndael.Key = key;
myRijndael.IV = IV;
myRijndael.Padding = PaddingMode.PKCS7;
using (ICryptoTransform encryptor = myRijndael.CreateEncryptor())
using (MemoryStream msEncrypt = new MemoryStream())
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(src, 0, src.Length);
csEncrypt.FlushFinalBlock();
return msEncrypt.ToArray();
}
}
finally
{
myRijndael.Clear();
}
}
}
//---------------------------------------------------------------------
public static Byte[] AesDecrypt(Byte[] src, Byte[] key, Byte[] IV)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
try
{
myRijndael.Mode = CipherMode.CBC;
myRijndael.Key = key;
myRijndael.IV = IV;
myRijndael.Padding = PaddingMode.PKCS7;
using (ICryptoTransform decryptor = myRijndael.CreateDecryptor())
using (MemoryStream msDecrypt = new MemoryStream())
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
csDecrypt.Write(src, 0, src.Length);
csDecrypt.FlushFinalBlock();
return msDecrypt.ToArray();
}
}
finally
{
myRijndael.Clear();
}
}
}
}
// put all the peices together
void SaveToFile(String fileName, Parametres obj)
{
ObjectXmlSerializer oxs = new ObjectXmlSerializer();
Byte[] bObj = oxs.Serialize(obj);
Byte[] bEncObj = CryptoSerivces.AesEncrypt(bObj, SomeKey, SomeIV);
using (FileStream fs = File.Open(filename, FileMode.OpenOrCreate))
{
fs.Write(bEncObj, 0, bEncObj.Length);
}
}
// I'll leave the reading up to you.

Compress and decompress a Stream with Compression.DeflateStream

I am trying to compress and decompress a Stream using Compression.DeflateStream. Compressing seems to work correctly since the code below compresses my Stream to a 110 bytes long array. However, reading the decompressed Stream results in an empty string.
class Program
{
static void Main(string[] args)
{
// Compress a random string value
string value = Path.GetRandomFileName();
byte[] compressedBytes;
using (var writer = new StreamWriter(new MemoryStream()))
{
writer.Write(value);
writer.Flush();
writer.BaseStream.Position = 0;
compressedBytes = Compress(writer.BaseStream);
}
// Decompress compressed bytes
Stream decompressedStream = Decompress(compressedBytes);
// here already applies: decompressedStream.Length == 0
using (var reader = new StreamReader(decompressedStream))
{
string decompressedValue = reader.ReadToEnd();
if (value == decompressedValue)
Console.WriteLine("Success");
else
Console.WriteLine("Failed");
}
}
private static byte[] Compress(Stream input)
{
using (var compressStream = new MemoryStream())
using (var compressor = new DeflateStream(compressStream, CompressionMode.Compress))
{
input.CopyTo(compressor);
return compressStream.ToArray();
}
}
private static Stream Decompress(byte[] input)
{
var output = new MemoryStream();
using (var compressStream = new MemoryStream(input))
using (var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress))
decompressor.CopyTo(output);
output.Position = 0;
return output;
}
}
Can anyone help me on this one?
Many thanks.
Fix your Compress function:
private static byte[] Compress(Stream input)
{
using(var compressStream = new MemoryStream())
using(var compressor = new DeflateStream(compressStream, CompressionMode.Compress))
{
input.CopyTo(compressor);
compressor.Close();
return compressStream.ToArray();
}
}
compressed stream was not flushed before returning the resulting byte array.
All those answers are far away from ideal form because all of you forgot that "using" disposing and closing streams its means that additional Close() is not needed. I think that ideal code will be like this:
public static class CompressionHelper
{
public static byte[] Compress(byte[] data)
{
byte[] compressArray = null;
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress))
{
deflateStream.Write(data, 0, data.Length);
}
compressArray = memoryStream.ToArray();
}
}
catch (Exception exception)
{
// do something !
}
return compressArray;
}
public static byte[] Decompress(byte[] data)
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);
}
}
decompressedArray = decompressedStream.ToArray();
}
}
catch (Exception exception)
{
// do something !
}
return decompressedArray;
}
}
Try closing the streams:
class Program
{
static void Main(string[] args)
{
// Compress a random string value
string value = DateTime.Now.ToLongTimeString();
byte[] compressedBytes;
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(value)))
{
compressedBytes = Compress(stream);
}
// Decompress compressed bytes
using (var decompressedStream = Decompress(compressedBytes))
using (var reader = new StreamReader(decompressedStream))
{
string decompressedValue = reader.ReadToEnd();
if (value == decompressedValue)
Console.WriteLine("Success");
else
Console.WriteLine("Failed");
}
}
public static byte[] Compress(Stream input)
{
using (var compressedStream = new MemoryStream())
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
{
input.CopyTo(zipStream);
zipStream.Close();
return compressedStream.ToArray();
}
}
public static Stream Decompress(byte[] data)
{
var output = new MemoryStream();
using(var compressedStream = new MemoryStream(data))
using(var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
{
zipStream.CopyTo(output);
zipStream.Close();
output.Position = 0;
return output;
}
}
}

Categories