Monitoring for non-pgp files - c#

For privacy reasons, I want to prevent my users from posting unencrypted files to my ftp site.
It is company policy that all data exchanges of sensitive data be encrypted with PGP.
I'd like to setup a program to monitor the ftp folders and whenever a new file is placed there, verify that it is in fact encrypted.
I can't just rely on the file extension because in some cases, our trading partners require a specific filename that doesn't have a .PGP on the end.
Is there a library or another method I can use to verify that a given file is encrypted?
I'm using C# and .NET on a windows platform.

You can easily detect the text mode PGP files. They start with
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.11 (GNU/Linux)
and end with
-----END PGP MESSAGE-----
This is of course not a sure way but good enough to prevent accidental unencrypted uploads.
I have do idea how the binary format looks like. You can try using "gpg -d " with an empty password and if it fails with "decrypt_message failed" then it is not a correct file. If it fails with bad key it is a PGP file. This is not a really good idea because the messages can change in the future.

You have to come with an heuristic approach to knowing if the file is encrypted or not. Usually, encrypted files tend to have a near random distribution of bytes. So if you read the stream of bytes, and bucket-count each byte, the distribution should be even, ie, there should be nearly as many 00h as AAh or FFh or 78h or etc (two hex values represent a byte) for each encrypted files.
Bad news is almost all compressed files (jpg, mp3, zip,...) also have this pattern of random bytes. Also, being an heuristical test, some encrypted files will fail, and some unencrypted files will be approved.

Related

Signing binary files (not code signing)

Is there a way to sign binary files? I'd like to sign my zip files to protect them from modification (to prevent installation of malicious software).
Signing XML is rather easy, but I'm not so sure about binary files. Is this even possible? All I can find about that matter is code signing (which is not what I want). There is no use in buying expensive certificates, it's just to ensure that update files aren't modified when they get installed.
I figure I have to work like that: Hashing the file, generating a key pair (probably using the hash for it) and then append the signature bytes to the file.
Vice versa, reading the signature bytes and verifying the hash against the public key of the signature.
But I don't think it's that simple. Do I have to consider certain things (like with XML that you need to canonicalize)?
I do not necessarily need code, but some detailed explanation about the process (any resources that explain that thoroughly would be okay as well).
When working with arbitrary binary files you can't modify their content so if you want to sign them you need to use a separate external file that contains the hash of the file you want to sign and also signs itself to prevent itself from being modified.
You then read this separate file, verify its personal signature, then verify the hash of each file it lists in its contents. You can use Catalog Files built in to windows (using MakeCat and SignTool to create them) or create your own following the same process.
Because you are only distributing updates, and if you are allowed to assume that the program loading the updates has not been modified, you don't need to "buy" a certificate. You could create your own "private CA", distribute that CA's certificate inside the updater, then use that Private CA's certificate to validate the catalog file.
I'm not sure what you mean as "binary file", but if you talk about PE format (Windows binary executable) you can generate own signature (encrypted hash) and put it inside of PE file in the same place as Windows authenticode certificate goes. Here is an open source tool to make such modifications:
http://blog.didierstevens.com/programs/disitool/

Creating a file that can be only used by my program. How do I differ it from other programs' files?

I create my file using File.WriteAllBytes(). Byte[] that is passed to File.WriteAllBytes() is encrypted by algorithm of my own. You need password that was used when file was encrypted (user of the program knows the password) to decrypt it. But when some file is opened by my program using File.ReadAllBytes() there are 3 situations:
File that is being opened is my program's file and user knows the password to open it.
File that is being opened is my program's file but user doesn't know the password to open it.
File that is being opened is not my program's file.
First one is easy to handle. 2nd and 3rd are same for my program because my program doesn't know the difference between encrypted byte[] and byte[] of some random file.
How do I differ these situations? I was thinking of adding some sequence of bytes to the end or beginning of byte[] before passing it to File.WriteAllBytes(). Is that safe? How do modern programs differ their files from other files?
You can give your file some structure before encryption, and check that the structure is there after decryption. If the structure is not there, it's not your file.
For example, you could compute a check sum, and store it in the first few bytes prior to the "payload" block of data. Encrypt the check sum along with the rest of the file.
When you decrypt, take the payload content, and compute its check sum again. Compare the stored result to the computed result to see if the two match. If they don't match, it's not your file. If they do match, very good chances are that it is your file.
This is not the only approach - the structure could be anything you wish, from placing a special sequence of bytes at a specific place to using a specific strict format (e.g. an XML) for your content, and then validating this format after the decryption.
[the file is] encrypted by algorithm of my own.
Be very careful with security through obscurity: coming up with an algorithm that is cryptographically secure is an extremely hard task.
Many many file format use "Magic numbers" in front of the file to determine their types. Use the first ... 4 bytes, write a custom sequence it it then read it when you load the file.

Can i use File.Encrypt for this purpose?

I have an application, its Name and Logo can changed directly from a TXT and a PNG file in the same directory.
I want to give the user the ability to change the Logo and Text File from another application that does the following :
Takes the Logo.png , Name.txt file paths and the directory of my Software then encrypt these two files and put them in the Directory of the Software
In the other hand. The software will Decrypt these two files and write them to Hard Disk to temp directory then use them to display the name and the logo.
I searched for the simplest and easiest way to encrypt a file and i found :
From the MSDN :
File.Encrypt():
Encrypts a file so that only the account used to encrypt the file can decrypt it.
Could someone please tell me what does it mean "only the account used to encrypt a file can decrypt it"
What about encrypting the application from Computer1 by Application1 then the file will be decrypted by Computer2 in Application2
Will the encryption work correctly ?
Edit:The purpose why I need to encrypt these two files is to avoid users from directly change the Logo and the Name of Application from the directory
This will encrypt the file, but not as you expect - and almost certainly not such that it can be decrypted by another application/user on a different computer.
The Encrypt method basically just toggles a feature of the underlying NTFS driver to encrypt the specified file on the file system itself. The nice feature is that it (typically) provides seamless file encryption for the user, but it isn't really portable encryption. It is the same as opening the file properties, clicking the advanced button and selecting the "Encrypt" checkbox.
More information on the encrypting feature of NTFS can be be found here: http://technet.microsoft.com/en-us/library/bb457116.aspx
No. You should use a proper encryption method such as those in System.Security.Cryptography namespace. There is a stream implementation for this, too, called CryptoStream, which you may wrap a FileStream with for encrypting files with.
This is related to Windows' EFS.
You can try it from Windows Explorer by right-clicking on the file, Properties, Advanced, Encrypt contents. The file data is automatically decrypted/encrypted on the fly as your app accesses it. But if another user logs in the machine and copies the file it will appear encrypted since the encryption is based on a user token.
This is may or may not be what you want and that depends on your intended use of that feature. If you don't want the user to be able to modify the data outside your app it won't be enough.

how encrypt an executeable file and make that encrypted file executeable without using extra file for decryption?

how can we encrypt an executeable file using c# and make that encrypted file still executeable without using extra file for decryption?
mean the decryption methods shuold be inside file.
how can i write something like that with c# language?
thanks in adavance
Storing encrypted data on clients machine and having it decrypt automatically means that you will have to store decryption key on that machine as well. This means that you can't effectively protect data and provide it to user. Such encryption is only used to slow down user from tampering with the data as time is needed to recover decryption key and algorithm.
If you want to encrypt code of the executable itself, to prevent user from tampering with it, this is a very very complex topic. It's only matter of persistence and time. You will not get an answer to such question in one StackOverflow post. You'll have to study PE and .NET file formats, operating system internals regarding executable loader as well as mscor*.
If you need to store some data
choose some encryption algorithm and encrypt your data into a file (see this question)
add encrypted file to your c# project as embedded resourse
in runtime access this file (see this question) and decrypt it (already discussed in first point)

Securely deleting a file in C#.NET

In a project I am doing I want to give users the option of 'securely' deleting a file - as in, overwriting it with random bits or 0's. Is there an easy-ish way of doing this in C#.NET? And how effective would it be?
You could invoke sysinternals SDelete to do this for you. This uses the defragmentation API to handle all those tricky edge cases.
Using the defragmentation API, SDelete
can determine precisely which clusters
on a disk are occupied by data
belonging to compressed, sparse and
encrypted files.
If you want to repackage that logic in a more convenient form, the API is described here.
You can't securely delete a file on a journaling filesystem. The only non-journaling system still in heavy use is fat32. On any other system, the only way to securely delete is to shred the entire hard drive.
EDIT
The reason secure delete doesn't work, is that that data used to overwrite a file might not be stored in the same location as the data it is overwriting.
It seems Microsoft does provide a secure delete tool, but it does not appear to be something that you can use as a drop in replacement.
The only good way to prevent deleted file recover, short of shredding the disk, would be to encrypt the file before it is written to disk.
It wouldn't be secure at all. Instead you may wish to look at alternative solutions like encryption.
One solution would be to encrypt the contents of the data file. A new key would be used each time the file is updated. When you want to "securely delete" the data simply "lose" the encryption key and delete the file. The file will still be on the disk physically but without the encryption key recovery would be impossible.
Here is more detailed explanation as to why "secure" overwrites of files is poor security:
Without a low level tool (outside of .net runtime) you have no access to the physical disk location. Take a filestream on NTFS, when you "open a file for write access" you have no guarantee that the "updated" copy (in this case random 101010 version) will be stored in the same place (thus overwriting the original file). In fact most of the time this is what happens:
1) File x.dat is stored starting at cluster 8493489
2) You open file x.dat for write access. What is returned to you by the OS is merely a pointer to the file stream abstracted by not just the OS but the underlying file system and device drivers (hardware RAID for example) and sometimes the physical disk itself (SSD). You update the contents of the file with random 1 & 0s and close the filestream.
3) The OS likely may (and likely will) write the new file to another cluster (say cluster 4384939). It will then merely update the MFT indicating file x is now stored at 4384939.
To the end user it looks like only one copy of the file exists and it now has random data in it however the original data still exists on the disk.
Instead you should consider encrypting the contents of the file with a different key each time file is saved. When the user wants the file "deleted" delete the key and file. The physical file may remain but without encryption key recovery would be impossible.
Gutmann erasing implementation
I'd first try simply to open the file and overwrite its contents as I would normally do it. Pretty trivial in C#, I won't even bother to write it. However I don't know how secure that would be. For one thing, I'm quite certain it would not work on flash drives and SSD's that use sophisticated algorithms to provide wear leveling. I don't know what would work there, perhaps it would need to be done on driver level, perhaps it would be impossible at all. On normal drives I just don't know what Windows would do. Perhaps it would retain old data as well.

Categories