Going back from signed hash with RSA SignHash - c#

I'm extremely n00b at this. I'm not even sure if what I'm asking is correct.
I've been asked to decrypt some package, but I found that the package is not being encrypted, instead the package (byte []) has a .zip inside protected with a password.
So now I have to retrieve that password. I tracked it in the code and came to this:
lSupraHeader = lCryptoTransformRSA.SignHash(lSupraHeader, CryptoConfig.MapNameToOID("SHA512"));
lSupraHeader is a Byte [] that contains (between other things) the password. If I get the string from lSupraHeader I can read the password, the problem is that after that "SignHash" I can't get it any more, well, I don't know how to do it.
That code was made a while ago, and change it is not an option for me.
Is there a way to retrieve that password from there? Is is correct what I'm asking whit what I provided or do I need something else?

Is there a way to retrieve that password from there?
No. Once data has been hashed, it cannot be unhashed.
SHA is also known as a "one-way hashing algorithm". It is designed so that any amount of data can be put into it, and a finite amount of data comes out. Such things are useful to check to see if two pieces of data are equal, although this method also has flaws (for which there are various workarounds).
Encryption, on the other hand, takes in data, uses a key, and spits out a bunch of random data roughly equal in size to the original data. Using the same key, the random data can then be unencrypted, or decrypted, to yield the original data.
Having said that:
I tracked it in the code and came to this:
How did you find that out? It would appear that you have access to source code and a debugger. If this is true, then see if you can find an "immediate window" in your debugger. You may be able to set a breakpoint, execute Console.WriteLine(whatever), and manually retrieve the password that way. Doing this would leave the original code untouched.

Related

Question about encrypting and authenticating instruction file in a .net desktop application

I want to do the below. What is the best way to achieve this?
I have a desktop app in C# which will be installed on multiple client machines.
The application is capable of doing an operation X but it needs some auxillary info which it can read from a file. This auxiliary info essentially provides some specifics that identify that machine where the operation should be run and what operation to run etc.
I will work with the client to get some of this auxilary info about his machine (say hostname/ip address etc) which I want to put in this file along with other info and generate it on my machine and share it with him/her to provide it to my software. I want to encrypt this data so that the structure of the data is not obvious to somebody who opens it. (I will get some of the machine identification info from the client, either via phone or email).
I want to somehow encrypt and secure this file such that only I can generate the file but any of my installations can read it. But since the contained info is specific to a machine it will be executed only on one machine (other machines will read but reject it since the given hostname/ip etc won't match that machine)
How do I do this? I want to make sure the below:
Only I can generate this file.
I need to somehow authenticate that this is generated only by me and not by somebody else.
But my software on client machines should be able to decrypt this.
I don't want to take a password from the customer etc. all the decryption logic should be in the installed software itself. I want to code it in.
When I researched this online, many talk about public and private cryptography but there they talk about encrypting with the public key and decrypting with the private key. But I don't think this will work since decryption is being done by my software at the client machine and so I shouldn't put the private key in my code. Because, from what I read, private key can generate public key so somebody could potentially generate that instruction file if I do this.
What is the best way to do this? Can I encrypt with private key and decrypt with public key? Is it ok if somebody gets hold of my public key (say they disassemble the C# code)? Any other good ways to encrypt and authenticate such that I hold the private data with me but code only harmless public keys/data in the application?
TIA.
Who are you trying to protect this from?
You are giving the end user your application binary. Assume they can decompile it and work out how it works. Or step through your code in a debugger, with access to the contents of every variable. Assume that an attacker can learn everything they need to know about how it works.
At best I would recommend creating a hash of the machine details and a salt value. Then create a signature of that hash.
Keep the salt and the public key of the signature as a constant in the application binary. Maybe XOR values together so an attacker has to think a little about how it works.
But anything more is pointless. Any attacker with more skills will just patch your program to delete the test entirely. So I wouldn't bother building anything too complicated.
Giving someone a program, and preventing them from using it, is like trying to make water not wet.
You have two questions
How do you encrypt the information, and
How can your client make sure the information came from you.
Those are orthogonal
I'll address the second on first - it's easier.
First, hash the file, and add the hash to the payload. Then generate a public/private key pair, then encrypt some known (but non-trivial) information with the private key and add that to the payload. You can distribute the public key with your app. If your app hashes the file and the hashes match and it can decrypt the known information and make sense of it, then it came from you and no one has changed it.
This is known as a digital signature. If you look up a digital signature provider and follow the docs, it should just work.
The encryption problem is more of an issue. There's pretty much no way to do what you want. If your app can decrypt the information using information you distribute with the application, then a determined bad guy can extract that key material and decrypt it.
However, you can use the RSA key container on the client to do the encryption when you install the app. The process is similar to using encrypted sections in a web.config file. Since you won't be following the encrypted config section cookbook the process is complicated.
I've done this before, but it was several jobs ago, so I don't have anything I can show you.
But, it will be encrypted so that it can be read only where it was encrypted. No two installations will recognize each others files.
That said...
Encryption seems like a heavy hammer to prevent your customers from being able to guess "the structure of the data [so that it] is not obvious to somebody who opens it"
Unless you have something worth protecting, you can probably get away with obfuscating the data. For example, you could have the data as JSON, but then use GetBytes on a Utf8Encoding to get a byte[] and convert that to a hex string. A determined hacker could decompile you code, figure out what you've done and reverse it, but that doesn't seem like a threat you really need to worry about.

What is the simplest way to check if a content of a file was changed in C#? Sha, crc32, md5 or something else?

I want to check if the content of a file changed.
My plan if to add a hash in the last line of the file.
Later on, I can read the file, hash it (hash everything except the last line) and compare it to the last line of the file (initial hash).
I cannot use the last modified date/time. I need to use a hash or any kind of coding stored inside the file. I use C# to code the app.
What is the most reasoneble/easiest way of doing this? I don't know which of the the following would be a good match for me: Sha1,2,3 - crc16/32/64 - md5? I do not need the method to be quick or secure.
Thank you!
It seems to me as if you're going to have a chicken or egg issue if you store the hash inside the file. You won't know the hash until you hash the file. But then when you hash the file and add that value to the end of the file, the hash will change. So clearly you need to hash the file without including the actual hash itself. You already said this, but I'm adding it again to clarify my next points.
The trick is that hash/sum algorithms give you the sum of the entire file (or byte stream, or whatever). They don't tend to give you a "running total" as it were. Which means you'll need to separate out the hash from the rest of the content before testing to see if it's changed. That is unless you write a custom hashing tool yourself.
This is of course possible using all hashing algorithms, but the fact that you are asking this question leads me to believe that you probably won't want the hassle of writing a custom (e.g.) SHA256 tool specifically designed to drop out when it reaches the stored hash.
To my eye, you have three choices:
Store the hash separately from your file - or at the minimum write a temporary file which does not contain the hash, and hash that. This would allow you to use a hashing tool already built into C# without any modification or fancy trickery. I know this does not exactly match your requirements as listed, but it's an option that you might consider.
You don't mention the size of the file, but if it is sufficiently small, you could simply slurp it up into memory minus the bytes of the hash, hash your in-memory data using a built-in tool, and then compare. This would again allow you to use built-in tools.
Use a custom hashing tool that purposely drops out when it reaches the end of the "interesting" data. If that's the case, I would unquestionably recommend a non-secure hashing method like CRC, simply because it will be so much easier to understand and modify the code yourself (it is much simpler code after all). You already mention that you don't need it to be secure, so this would meet your requirements.
If you decide to go with option #3, then I would suggest schlepping over to Rosetta Code to search for a CRC algorithm in C#. From there you can read your file, subtract out the bytes of the hash, send the remainder through your hashing algorithm. The algorithm listed there processes all bytes at once, but it would be trivial to turn the accumulator into a parameter so that you could send data in chunks. This would allow you to work on an arbitrarily large file in situ.
[EDIT] FWIW, I have already gone down a similar path. In my case I wrote a custom tool which allows us to incrementally copy extremely large files over the WAN. So big that we had problems getting the file to copy safely. Proper use of the tool is to remote the source server, pre-run a CRC32 check and save the sums at arbitrary intervals. Then one copies the CRC32 checks to the client side, and starts copying the file. Should the target get stopped in the middle, or possibly corrupted somehow, one can simply supply the name of the local partial, the remote source, the file containing CRC32 sums, and finally a target. The program will start copying from the local partial, and will only start copying from the remote when a partial CRC32 sum issue is found. Our problem was that a simple resume at the end of the bytes copy did not always work. Which was frustrating since it takes so long to copy. My team mates and I laughed several times that we might try USB drives and homing pigeons...
What are you trying to protect yourself against?
Accidental change? Then your approach sounds fine. (Make sure to add handling for when the last line with the hash was deleted by accident too.)
Malicious change? Then you'd need to hash the file content plus some private key, and use a secure hashing algorithm. MD5 is good for accidental changes because it is fast, but cryptographically it is considered broken.

Using BCrypt.Net to simulate Devise Password Encryption?

I am trying to a pretty simple task here. I have a server that I am running which has a MySQL instance running on it, which my rails app uses to populate. Unfortunately for me I used devise to do all my user management and now am a little stuck.
So I have a C# application that I am writing. I want to simply verify the user and password through the MySQL database that I have already in place.
Right now here is what I know (or think I know):
Devise uses Bycrypt to do a one way encryption on their passwords which are then stored in the database. The problem is that I am not sure how to implement bycrypt properly to produce the proper encrypted passwords to validate.
Here is my current process for generating my hashed password:
string pass = password.Text;
string mySalt = BCrypt.Net.BCrypt.GenerateSalt();
string myHash = BCrypt.Net.BCrypt.HashPassword(pass, mySalt);
I think that this must be really wrong. I just don't quite know what I am missing here or what I am doing wrong. I will keep googling around and if I come up with an answer I will post back. Also if I broke any editting rules or something just let me know so I can fix them right quick.
Thanks in advance for your time :)
I think your problem is your generating the Salt each time you are hashing the password to verify against the database. You need to use the same Salt value that was used when the password was initially generated.
Alright so my question was actually pretty silly but for anyone else with the same logical fallacy as me I'll explain.
By default Devise does it's encryption using BCrypt, which is typically done with Blowfish, when they do this they always use BCrypts generate salt function which produces a random salt for each hashing of the password.
Because of the random salt BCrypt includes a utility function called Verify(password, hashed_pass). This function allows the testing of a non encrypted password and hashed pass to be compared. Nifty and very useful

Ways to 'carry' bytes and run it in c#?

I need my program to be secure as it's contents include personal information like IP (a private IRC chat if you must know). My plan is to read the bytes of the program and then create a symmetric encryption algorithm like AES to encrypt the byte arrays, to increase security I have added other minor things which can take care of debugging and emulators for example. Then I will use codedom to create my stub that 'carries' these encrypted bytes. There are 2 ways that I know which can 'carry' the code:
Append encrypted bytes to stub in order for it to decrypt, write and run. (Known as dropping)
Add it to the stub's resources so it can decrypt and load it so it which then is able to run it in Memory.
I could have 4 ways by adding to resource then decrypt, write and run or appending then decrypt, load and run in the memory. I could also make my own little obfuscation in the code but I doubt it will make much difference.
Method 2 seems to have been abused by people and is detected by the Anti-Virus and it is really annoying to get your project blocked by your anti-virus every time you debug. Enough of the excuses it will just be a false positive for the user when all the program is doing is protecting itself from being easily disassembled with programs such as the Red Gate Reflector.
Including the database information e.g. SQL login methods are still going to be analyzed if disassembled:
Are there more ways of doing this?
There is no way of doing what you describing. Get rid of it.
Another way to do such a thing would be to have a webservice that the user has to authenticate against which then sends the sensitive information over a secure channel (e.g. SSL/TLS).
An second approach could be that you
Enrypt the information
Embed the encrypted version of the sensitive informations into the executeable
Ask the user for a symmetric key at runtime (e.g. he has to enter the "passwort" for the data)
Use the symmetric key to decrypt the information
Use the information
The big disadvantage here is, that if the symmetric key (e.g. the password) is stolen in any way, the attacker can then get all that enrypted information.
What about SecureString? Seems like this would handle hiding the information within the program without a whole lot of bother. If the memory is dumped during execution then the data will be encrypted.

Beginner Encryption, "Master Password" Question

I'm writing a program that, using Rijndael, will encrypt and decrypt files/folders using a user chosen password. Currently, when the user wants to encrypt something, they have to enter a password, that password is used to encrypt and when the user is ready to, decrypt the file/folder.
However, I would like to have a "master password" that will allow the user to only enter the password once in a "preferences" portion of the program, and then the program will automatically use that password for all encryption/decryption. This way they don't have to put in a password every time they want to encrypt/decrypt.
Now, since programs like this are prone to many different kinds of attacks, how do I safely store the user's "master password" so someone couldn't get a hold of it? Storing it in the program in plain text is obviously not a good idea, so I could encrypt/decrypt the password with another password, chosen by me, and stored in the program.
However, again, if someone gets access to the password chosen by me to encrypt/decrypt the master password, then they could decrypt the master password and again, that wouldn't be good.
SO! How do programs safely do this?
Currently I'm saving the "master password" by encrypting it using my own, chosen password, and storing it in a User-scoped setting. If you think this isn't a good idea, please tell me why and what would you change about the process I currently have implemented?
Thank you!
Review this:
http://www.redkestrel.co.uk/Articles/StoringSecrets.html
It's a great article on your options.
That said, I think your use case is already pretty well natively covered by windows itself through EFS....
http://technet.microsoft.com/en-us/library/cc700811.aspx
Just wanted to add one thing:
It is fundamentally impossible to protect a "secret" from those who have physical access to the machine. This has been proven time and again even for hard drives that support native encryption schemes.
All you can do is make it somewhat difficult for those that have no idea what they are doing.
The fundamental problem is that something has to have access to the decryption key. Whether it's the BIOS of the machine, Firmware of the Harddrive, or even if it's stored in some folder hidden through DPAPI. Which means the only effective way is to force the user to supply the necessary credentials when it's time to encrypt / decrypt the files.
If those credentials are sufficiently short then it's possible to use brute force to get to them. Right now the recommendation is to use minimum key lengths of 128 bits or greater. Of course, if you are limited to use common letters then the number of bits to test goes down dramatically. And if you allow values such as those found in hacking dictionaries then the time to crack goes down further.
Another wrinkle are keyloggers. If one's installed (and they can be hidden from most users) then all an attacker has to do is wait for the user to type their decryption password in and forward that to an interested party.
Heck, for the truly paranoid, there are devices that can detect what you typed based solely on the sound your keyboard makes as you type. For others, RAM maintains state for a certain period of time even after the machine has been shut off...
So, what does all this mean? First, you have to ask them to provide the credentials on each encrypt / decrypt request. Second, they have to be sure that no keyloggers are installed. Third, the credentials can't be something easily remembered. Fourth, the computer cannot be in a physically accessible location. Fifth, even the keyboard has to be secured...
All of which adds up to a situation that says if its on a computer, someone else can get it.
Do you know why websites won't tell you your password when you lost it and they ask for a new one?
Because they don't know it. Yes, they don't know it. They hash it and hash it good so they can only check your input password's hash against the one in the database.
Why all that?
Because they cannot store it safely.
They cannot encrypt it safely.
This is a similar case.
The best way is not to use a master password.
When you encrypt a file, ask for a password and encrypt with the hash of the password.
When decrypting, do ask for a password and attempt to decrypt.
If it fails then it's wrong.
If it's okay then it's the right one.
You can add some (shorter) dummy data before the file's contents that you can use to check the key.
If you try to use that to store the master password, you will enter an infinite loop of security, which is not a good idea.
You'll encrypt the password, and then encrypt the key used and then encrypt the key used to encrypt the first key etc.
Edit: I am sorry about the discouraging nature of this answer but what you need to do is truly impossible.
Consider storing you master password in memory using the SecureString Class.
I'll be frank about this. Leave security to security experts. Security is not easy, and is very very hard to get right even for people who are supposedly experts in the area.
If you really have to store sensitive data that your users are expecting to be secure then asking in SO on how to do it is definitely NOT a good sign and not the way to go. You should seek professional guidance or consider using well tested implementations available in the market or in Windows itself.
Don't persist the user's password, take a hash and be sure to salt it. Use the hash to encrypt and decrypt the files. Beware if the user forgets their password you will not be able to recover it for them however you could still decrypt the files for them. This also means your app would be vulnerable to somebody hacking/patching it to get it to decrypt files without providing the password.
If the encryption method is standard, documented, obvious and/or well-known then to prevent hackers from just reading the hash and using it to decrypt the files themselves you could do this: use the stored hash along with some other info to generate a new hash that you then use to encrypt/decrypt the files and never persist. The other info could be made up of the size of the file, the created date, etc. Hackers could use this info but they would have to hack/reverse engineer your app before they know they need it. Technically it's security through obscurity since those keys are hidden in plain view.

Categories