I am writing a zip file generator which will be consumed by a third party using a specific encryption algorithm
I have found the enumeration of algorithms here:
ICSharpCode.SharpZipLib.Zip.EncryptionAlgorithm
But I don't know how to apply the algorithm to a given zip archive.
Here's my code.
using (FileStream fsOut = File.Create(fullPath + ".zip"))
using (var zipStream = new ZipOutputStream(fsOut))
{
zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
zipStream.Password = "password";
using (MemoryStream memoryStream = new MemoryStream())
using (TextWriter writer = new StreamWriter(memoryStream))
{
// redacted: write data to memorytream...
var dataEntry = new ZipEntry(fullPath.Split('\\').Last()+".txt");
dataEntry.DateTime = DateTime.Now;
zipStream.PutNextEntry(dataEntry);
memoryStream.WriteTo(zipStream);
zipStream.CloseEntry();
}
}
Edit
DotNetZip allows you to also choose Zip 2.0 PKWARE encryption algorithm.
As I understand from reading the code and forum posts, EncryptionAlgorithm exists to document the values available in the Zip standard and not as an option for the end user.
The encryption algorithms that are actually available to you are AES128 and AES256. You apply the algorithm on each entry by assigning the AESKeySize property.
So in your case:
// Specifying the AESKeySize triggers AES encryption. Allowable values are 0 (off), 128 or 256.
// A password on the ZipOutputStream is required if using AES.
dataEntry.AESKeySize = 256;
(the comments come from this page https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples/6dc300804f36f981e516fa477219b0e40c192861)
Related
the below code was used several years ago to generate a binary that was used for encrypting some files, using DES algorithm (I know DES is weak and AES is recommended, but those are not my requirements).
the binary has been encrypting those files, which were successfully decrypted by the submission portal.
DES being a bijective algorithm for a single key, a single input should always yield the same output, and one output can only be obtained from one input.
However, recompiling the code today, the output file obtained is different than what the old binary used to yield. Meaning if i tried submitting the new file on the test portal, it would fail.
However, the code itself has not changed.
As to why I want to recompile the code:
My goal was to migrate the function to another language, and seeing as I was unable to obtain the same output, decided to try step-by-step debugging it in C# to see where the difference was coming from - except the old and new C# binaries are also returning different outputs...
Edit 1:
the input and outputs as requested:
input: hello world
old out: 5ELrrBHwxbNDT9Clywhhvg==
new out: RYZbVdhS+c5nRErRgZxZiw==
but since the key above is not the real key anyway, not sure it would be of help.
Edit 2:
tried all different combinations of CipherMode and PaddingMode, no match still.
Could the .NET / Framework / C# version matter? (newbie question, first time using C#)
although it shouldn't since the underlying algorithm is the same. Any ideas?
the C# code:
String strCryptKey = "12345678";
Byte[] strIVkey = new Byte[8];
strIVkey[0] = 0x13;
strIVkey[1] = 0x14;
strIVkey[2] = 0x15;
strIVkey[3] = 0x16;
strIVkey[4] = 0x17;
strIVkey[5] = 0x18;
strIVkey[6] = 0x19;
strIVkey[7] = 0x20;
string sourceString;
using (var streamReader = new StreamReader(args[0], Encoding.UTF8))
{
sourceString = streamReader.ReadToEnd();
byte[] sourceArray = Encoding.UTF8.GetBytes(sourceString);
MemoryStream tempM = new MemoryStream();
DES des = new DESCryptoServiceProvider();
CryptoStream encStream = new CryptoStream(
tempM,
des.CreateEncryptor(Encoding.UTF8.GetBytes(strCryptKey), strIVkey),
CryptoStreamMode.Write
);
encStream.Write(sourceArray, 0, sourceArray.Length);
encStream.FlushFinalBlock();
String encryptedString = Convert.ToBase64String(tempM.ToArray());
File.WriteAllText(args[1], encryptedString);
}
I have a PGP key pair that I created with Kleopatra and I want to know how I can access it using C#?
I am using the PgpCore library to decrypt a file, but it appears I need to feed it the key file and I don't know where it is stored on the machine or the best way to access it.
Is there some way I can query Kleopatra with the ID of the certificate to retrieve the key?
Super late to this, but going through this myself. I think you'll have to export the keys, and then point at the file path where you store them to use in C#
Kleopatra
Export private key: right-click and select 'backup secret keys'
Export public key: right-click' export keys' to back up the public key.
PGPCore code for encryption and decryption:
Encryption using the public key:
// Load keys
EncryptionKeys encryptionKeys;
using (Stream publicKeyStream = new FileStream(#"C:\TEMP\Keys\public.asc", FileMode.Open))
encryptionKeys = new EncryptionKeys(publicKeyStream);
PGP pgp = new PGP(encryptionKeys);
// Reference input/output files
using (FileStream inputFileStream = new FileStream(#"C:\TEMP\Content\content.txt", FileMode.Open))
using (Stream outputFileStream = File.Create(#"C:\TEMP\Content\encrypted.pgp"))
// Encrypt
await pgp.EncryptStreamAsync(inputFileStream, outputFileStream);
Decryption using the private key and password:
// Load keys
EncryptionKeys encryptionKeys;
using (Stream privateKeyStream = new FileStream(#"C:\TEMP\Keys\private.asc", FileMode.Open))
encryptionKeys = new EncryptionKeys(privateKeyStream, "password");
PGP pgp = new PGP(encryptionKeys);
// Reference input/output files
using (FileStream inputFileStream = new FileStream(#"C:\TEMP\Content\encryptedContent.pgp", FileMode.Open))
using (Stream outputFileStream = File.Create(#"C:\TEMP\Content\decrypted.txt"))
// Decrypt
await pgp.DecryptStreamAsync(inputFileStream, outputFileStream);
Obviously change the file paths to the corresponding key path, , encrypt = public, decrypt = private
I have a desktop application developed in c# language that has some games that the users play and the App will store their names, scores and other information on the client computer, currently I am using an xml file to store the info of the user, but a drawback is that the user can edit the file manually and mess with it by editing their scores or name.
I want to store the info so that the users can not manually edit it, so what file format should I use or should I encrypt the data before storing in the file.
My file is stored in the C:\Users\jobs\AppData\Local folder
tnx
If you need some basic protection against an average PC user you probably want to use something really simple, like this:
// data for example
var data = new XElement("gamedata",
new XElement("player", new XAttribute("name", "t0taln00b"),
new XElement("score",
new XAttribute("game", "bite your elbow"),
new XAttribute("score", 9000),
new XAttribute("progress", "19 %"))
)
);
// set up encryption.
// You probably will want to do this once at program startup and store Key and IV globally
var rnd = new Random(12562);
var keysize = 128;
byte[]
Key = new byte[keysize / 8],
IV = new byte[keysize / 8];
rnd.NextBytes(Key);
rnd.NextBytes(IV);
// lets encrypt
using (Aes aes = new AesManaged() { Padding = PaddingMode.PKCS7, KeySize = keysize })
{
aes.Key = Key;
aes.IV = IV;
using (Stream file = new FileStream("save.xml.aes", FileMode.Create, FileAccess.Write))
using (Stream encrypter = new CryptoStream(file, aes.CreateEncryptor(), CryptoStreamMode.Write))
data.Save(encrypter);
}
//and decrypt
using (Aes aes = new AesManaged() { Padding = PaddingMode.PKCS7, KeySize = keysize })
{
aes.Key = Key;
aes.IV = IV;
using (Stream file = new FileStream("save.xml.aes", FileMode.Open, FileAccess.Read))
using (Stream decrypter = new CryptoStream(file, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
var loaded = XElement.Load(decrypter);
Console.WriteLine(loaded.ToString());
}
}
Please note that this would be an extremely weak encryption. Keys generated by System.Random cannot be strong, and a whole encryption code can be revealed with tools like .NET Reflector.
If you need really strong encryption i would suggest having something like a webserver which encrypts the file with an asymmetric encryption and keeps the private key secure. This will not absolutely prevent a hacker from reading the file, but at least will make you totally sure that he cannot modify its content.
I'm working on a encryptor application that works based on RSA Asymmetric Algorithm.
It generates a key-pair and the user have to keep it.
As key-pairs are long random strings, I want to create a function that let me compress generated long random strings (key-pairs) based on a pattern.
(For example the function get a string that contains 100 characters and return a string that contains 30 characters)
So when the user enter the compressed string I can regenerate the key-pairs based on the pattern I compressed with.
But a person told me that it is impossible to compress random things because they are Random!
What is your idea ?
Is there any way to do this ?
Thanks
It's impossible to compress (nearly any) random data. Learning a bit about information theory, entropy, how compression works, and the pigeonhole principle will make this abundantly clear.
One exception to this rule is if by "random string", you mean, "random data represented in a compressible form, like hexadecimal". In this sort of scenario, you could compress the string or (the better option) simply encode the bytes as base 64 instead to make it shorter. E.g.
// base 16, 50 random bytes (length 100)
be01a140ac0e6f560b1f0e4a9e5ab00ef73397a1fe25c7ea0026b47c213c863f88256a0c2b545463116276583401598a0c36
// base 64, same 50 random bytes (length 68)
vgGhQKwOb1YLHw5KnlqwDvczl6H+JcfqACa0fCE8hj+IJWoMK1RUYxFidlg0AVmKDDY=
You might instead give the user a shorter hash or fingerprint of the value (e.g. the last x bytes). Then by storing the full key and hash somewhere, you could give them the key when they give you the hash. You'd have to have this hash be long enough that security is not compromised. Depending on your application, this might defeat the purpose because the hash would have to be as long as the key, or it might not be a problem.
public static string ZipStr(String str)
{
using (MemoryStream output = new MemoryStream())
{
using (DeflateStream gzip =
new DeflateStream(output, CompressionMode.Compress))
{
using (StreamWriter writer =
new StreamWriter(gzip, System.Text.Encoding.UTF8))
{
writer.Write(str);
}
}
return Convert.ToBase64String(output.ToArray());
}
}
public static string UnZipStr(string base64)
{
byte[] input = Convert.FromBase64String(base64);
using (MemoryStream inputStream = new MemoryStream(input))
{
using (DeflateStream gzip =
new DeflateStream(inputStream, CompressionMode.Decompress))
{
using (StreamReader reader =
new StreamReader(gzip, System.Text.Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
Take into account that this doesn't have to be shorter at all... depends on the contents of the string.
Try to use gzip compression and see if it helps you
I am trying to use BouncyCastle to encrypt a file using the PKCS 7 file standard. Here is the code I have which outputs a p7m file. When I go to decrypt the file (using Entrust) I am prompted for my key store password, so it knows the file was encrypted for me using AES 128, but it cannot decrypt the body of the file. Something has to be going wrong on the encrypt.
byte[] fileContent = readFile(filename);
FileStream outStream = null;
Stream cryptoStream = null;
BinaryWriter binWriter = null;
try
{
CmsEnvelopedDataStreamGenerator dataGenerator = new CmsEnvelopedDataStreamGenerator();
dataGenerator.AddKeyTransRecipient(cert); //cert is the user's x509cert that i am encrypting for
outStream = new FileStream(filename + ".p7m", FileMode.Create);
cryptoStream = dataGenerator.Open(outStream, CmsEnvelopedGenerator.Aes128Cbc);
binWriter = new BinaryWriter(cryptoStream);
binWriter.Write(fileContent);
}
And when i try and decrypt the file using BouncyCastle I get this error when i pass the file contents to a CMSEnveloped Object:
IOException converting stream to byte array: Attempted to read past the end of the stream.
Any ideas whats going on here?
I used the EnvelopedCMS class to accomplish this.
http://msdn.microsoft.com/en-us/library/bb924575(VS.90).aspx