Use SHA512 to hash a password to encrypt data - c#

I have a C# application in which I sometimes have to encrypt some data (XML file). Basically, the problem is I cannot store any keys on a server, or directly in the code, as .NET apps can be easily disassembled with for example dotPeek.
So basically my app would encrypt XML file and save it on disk, and then would be able to decrypt it.
I came up with an idea to ask for a passphrase every time a user wants to encrypt/decrypt the data. This passphrase would be hashed with SHA512 and the resulting bytes would be used as a key to encrypt the data. Then if the user wants to decrypt the file, they are asked for a passphrase again and this passphrase is used to decrypt the file (it may fail if the user enters a wrong passphrase).
So my first question would be: Is it actually a good idea?
My second question is about the implementation. I have hashing, serialization, deserialization, but I don't know which encryption algorithm should I use (I guess not RSA as the data to be encrypted would be really long) and then can I pass the passphrase as a key to this algorithm?

You've stumbled upon the idea of a Key Derivation Function (KDF). What you're suggesting is, with a few differences, an excellent idea and one used often. The small-ish issue is that SHA-512 alone is not a good KDF. I recommend you read about PBKDF2 (in .NET, the implementation is called Rfc2898DeriveBytes). Password hashes like bcrypt and argon2 are also very viable choices.
In regards to your question regarding the encryption algorithm, AES is currently considered the "standard" symmetric encryption algorithm. There are many other viable options however. Just ensure you aren't using DES or Triple-DES, they're dated algorithms. Also ensure you're using a secure block mode. GCM is arguably the "best".

Related

Decrypt string using PHP that was encrypted using c#

I need to decrypt a string, returned from an API that was originally encrypted using c# functions based on those here >
http://www.codeproject.com/Tips/704372/How-to-use-Rijndael-ManagedEncryption-with-Csharp
I need to decrypt using PHP.
A password and a key have been provided I've made several attempts to decrypt using openssl_decrypt, but I'm unsure how to use the key in the decryption?
[update] I have been told that the password I have been given is the basis for the iv, and that the padding is PKCS7, the problem is that I have no idea how to create the iv.
I have the following example input/keys, but I'm not sure how to use the password as I've been told it is the iv do I need to pad it to the correct length, if so how?
Original string: 'Mondays Suck'
Password/salt: 'this_is_the_password'
Input key: 'this_is_the_input_key'
Encrypted String: 'mAqsxJaA0jpQdefBPug2tw=='
If there indeed is any ciphertext packing going on, it would be to include the initialization vector (IV), assuming one was even used in the first place.
In short, if I encrypted a string with AES-128:
I'd likely be using PBKDF2 to take a weak passphrase and a salt to generate secret key material used to do the encryption itself.
I'd generate a message-specific (i.e. one-time use) initialization vector for ciphering
I'd then use the secret key [material] and IV generated in the previous steps to encrypt the string using AES-128: E(plaintext, key, iv)
If the string is longer than 16 bytes, I'd have to also use an encryption mode such as CBC, CTR, etc.
For convenience, I would "pack" the IV (not required to be kept secret) in front of the ciphertext by simply concatenating: iv+ciphertext
If I was serious about doing it right, I would generate a message authentication code of the ciphertext and append that as well such that I would now have: iv+ciphertext+mac
On decrypt, I would then verify the MAC before decrypting (if I was to do it right), and I would then need to separate the IV from the ciphertext, and then run it through my decryption routine: D(ciphertext, key, iv).
Another thing to keep in mind is encoding as sometimes we pass around Base64-encoded strings as a more print-friendly format than raw data. You of course would have to decode that before working on unpacking, decrypting, etc.
For academic purposes, I created Crypto Implementation (DRAFT) back when I was teaching myself crypto and wanted to document processes and best practices as well as keep all "moving parts" in view as a reference when I had to work on this stuff. Lots of rules to follow, but all in all, a lot of good learning and professional development opportunities.
Hope that helps some!
Edit: Per my comment below, I just looked at the original source code for the C# implementation. It appears the only way to decrypt this in PHP would be to have a PHP equivalent of C#'s Rfc2898DeriveBytes as this is the part responsible for generating your IV. Study the DecryptRijndael routine and you'll see where it gets the IV from (it basically implies using the same salt). If you truly have no control or influence over the encryption routine, you might be inclined to hack up a solution involving using C# DLLs in PHP and then call the DecryptRijndael method from PHP.

Encrypting passwords for use in Database AES or RijndaelManaged?

I am having a dilemma in choosing which encryption to use.
I have to store passwords in a database. I would like to encrypt the passwords. I am using C# and am looking for reasons between AES and RijndaelManaged.
I have looked for a succinct answer but I can find none which clearly states which is better today.
If one can provide a link, I would appreciate it.
If possible, you should use salted passwords with a one-way hash.
Hash and salt passwords in C#
In looking at this article The Differences Between Rijndael and AES, the differences mentioned are negligible considering you want to only encrypt passwords (assumingly of small length < 30 characters).
Also see Is the RijndaelManaged Class in C# equivalent to AES encryption?

Which encryption algorithm to use for password-protecting data?

I am currently thinking of something to do as my final project for my C# class. The thing that came up to my mind was a password-protected data storing application which would require a password to access data stored in a binary file.
The problem is that I am not sure which encryption to use if I would decide to do this project.
What encryption would fit best this scenario? Which encryption is the best?
Just little more info what I have planned.
First, user must specify the user name/password information to save the data. Data would be saved in binary file which later should be able to view after login information are correct.
I think you should go with AES in CTR mode.
A C# implementation of Rijndael (the underlying cipher of AES) can be found here.
There is probably not such a thing as the best encryption algorithm, but it is what everybody else is using right know.
To clarify further:
This is how encryption works:
Plaintext -> [encryption] -> Ciphertext -> [decryption] -> Plaintext
This is what you would have to use for a password manager.
This is how hashing works:
Message -> [hashing] -> Hash -> [???] -> Message
You can (and should) use hashing algorithms to store (hashed) passwords in a database for authentication purposes (e.g. log into a website). To do so, you use a salt or a key-based message authentication code.
Instead of "dehashing" the hash stored in the database, you just hash the user input and verify if it matches. This does not work for an application like a password manager.
With a cryptographically secure hashing function (like SHA-512), it is currently impossible to "dehash", i.e., even if you know the hash, you cannot retrieve the message.
Not sure if this is an answer to your question, but alot of systems that store usernames and passwords tend to just hash the passwords, so you never actually store the users password, just the one way hashed version of it. That way when they try to login again you just hash the password and compare it to the existing one.
MD5 is the simplest one, but I believe SHA256/512 is one of the better ones to use, this is a one way hashing algorithm though, and may not be applicable to your situation if you need to be able to ever gain access to the plain text version of their passwords. Usually this isnt an issue as you can just get them to change their passwords and a user never really needs to see their password in plain text.
If you cannot use one way hashing, then just use blowfish or some other simple two way encryption algorithm. The internet is full of different .net encryption providers. If it is homework I dont think it will really matter, as long as you can show a working knowledge of why and when you would use encryption you should get marks.

How to encrypt variable length text in PHP and C#?

For a game I am currently making I am in need of encrypting a variable length string (this could be a short as 10 characters or a full XML document) in C# and then sending this to a PHP script which decrypts and processes the information. I am unfortunately completely in the dark when it comes to cryptography and am having trouble finding something that can suite my needs in this case. Is there a library which can do this kind of variable length encryption across multiple platforms such as this?
AES, sometimes called Rijndael, might be a choice for you. It's a standard created by the National Institute of Standards and Technology, an agency of the US government.
It's available in PHP using the mcrypt extension, and there seems to be a managed library built in to the .Net framework. See this previous SO question for more on C#'s implementation. I know little about C# and .Net, but the answer there has 23 votes, so is likely to be on to something. (Edit: #Fun Mun Pieng's answer contains a reference to AES itself, and might be more up to date or otherwise useful than the post I linked.)
AES is a block cypher, meaning that it operates best on lengths of text of a specific set of lengths. There are multiple operation modes and padding schemes that you'll want to read up on and select. If you use the same operation mode and padding on both sides, you should have perfect interoperability.
Keep in mind that AES is a symmetric cypher. This means that the same key is used to both encrypt and decrypt. It might not be the best choice for you. If your users gain access to the key, the encryption becomes worthless.
Public-key cryptography might be a better choice for you. It uses two keys instead of one. Data encrypted using the public key can only be decrypted by the private key. This means that you don't need to worry too much about the public key falling into the wrong hands, as no data can actually be decrypted about it. It may allow troublesome users to still craft legit-looking messages, though.
PHP's best option for public-key cryptography is the standard OpenSSL extension, which uses the industry standard RSA system. A quick look at Google suggests that there's also native .Net support for RSA as well. Like AES, you may need to worry about modes of operation or padding, but again you should get complete interoperation by using the same methodology on both sides. The one possible annoyance will be initial key creation, and how each side wants to store private and public keys.
For the C# part, you could use the System.Security.Cryptography namespace. Eg:
System.Security.Cryptography.Aes aes = System.Security.Cryptography.Aes.Create();
System.Security.Cryptography.ICryptoTransform enc = aes.CreateEncryptor();
// byte[] input;
// byte[] output = new output[512]
int size = enc.TransformBlock(input, 0, input.Length, output, 0);
I have no idea how to do it for the PHP end, but I'm sure you can find a way to decrypt from standard algorithms such as DES, AES, RSA. And remember to pass the key.
For your case, I guess asymmetric encryption is more suitable.

MD5 Hashing Given a Key in C#

I've been looking for a way to hash a given string in C# that uses a predetermined key.
On my adventures through the internet trying to find an example i have seen lots of MD5CryptoServiceProvider examples which seem to use a default key for the machine, but none of them that apply a specific key. I need to have a specific key to encode data as to synchronize it to someone else's server. I hand them a hashed string and an ID number and they use that analyze the data and return a similar set to me. So is there anyway to get md5 to hash via a specific key that would be consistent to both.
I would prefer this to be done in C#, but if its not possible with the libraries can you do so with some web languages like php or asp?
Edit: Misunderstood the scenario I was thrown into and after a little sitting and thinking about why they would have me use a key it appears they want a key appended to the end of the string and hashed. That way the server can appended the key it has along with the data passed to ensure its a valid accessing computer. Anyways... thanks all ^_^
Edit2: As my comment below says, it was the term 'salting' I was oblivious to. Oh the joys of getting thrown into something new with no directions.
MD5 is not encryption - it's a hash. It doesn't allow a string to be decrypted.
You're looking for a symmetric encryption algorithm. It uses the same key to encrypt and decrypt. Trying to use encryption functions without understanding them is dangerous. Even if you think you understand them, you can make a mistake.
If you're transferring data to another person's server, you may be better off using something like gpg to encrypt the file using a symmetric key you both agree on over the phone, or perhaps some public-key crypto. This way, you don't write any crypto code, and it's safer (not completely secure, mind you, but safer).
Edit: I'm still trying to decipher your requirements.
MD5 is an unkeyed hash function - there is not key in use at all. So let's say the server sends you a giant string, or a file, and a hash of it. You would then MD5 the string or file, and compare the hash you computed with the hash they sent. If they match - the data was not corrupted in transit. That doesn't mean no one tampered with what they sent you in transit, because MD5 has no "secret sauce" to it. I can md5 anything I want and send it to you.
A HMAC is a keyed hash function. It has a secret ingredient that only you and the group you're communicating with should know - the secret key. If they send you a long string or file, and a HMAC, you can compute the HMAC yourself, compare your HMAC and theirs, and if they match, the data was not corrupted in transit, nor was the data tampered with.
MD5 is a hash function and, strictly speaking, is not used to "encrypt" a string. It produces a 128-bit "Message Digest" (hence the MD in the name) that is used as a kind of fingerprint for the input string.
Tom's right: MD5 is just a one-way hash, you can't decrypt it. Try these links:
Symmetric Key Encryption in C#
Public-Key RSA Encryption in C#
You can use AES from C# to do the type of encryption you are looking for. Here's an article on how.
You should use one of the classes inherited from SymmetricAlgorithm, for instance :
AesCryptoServiceProvider
DESCryptoServiceProvider
RC2CryptoServiceProvider
TripleDESCryptoServiceProvider
So, why does the following test fail if both input strings are identical?
[TestMethod]
public void MD5HashTest()
{
var hash1 = (new MD5CryptoServiceProvider()).ComputeHash(new System.Text.ASCIIEncoding().GetBytes("now is the time for all good men."));
var hash2 = (new MD5CryptoServiceProvider()).ComputeHash(new System.Text.ASCIIEncoding().GetBytes("now is the time for all good men."));
Assert.AreEqual(hash1, hash2);
}

Categories

Resources