Encrypt a string twice... Good, Bad or Ugly? - c#

I'm working on an encryption class that is using Rijndael algorithm (C#, ASP.Net 4.5), and out of curiosity I was wondering how beneficial would it be to encrypt the string twice. I mean Encrypt the string with a key and then Encrypt the resulting encryption with another key?
Does this make it that much more secure (I know nothing is ever secure and there could be other holes in my software that could be used to exploit)? Is it worth the CPU overhead (not sure how heavy this is but I can't imagine it would light)?
I was looking for some suggestions online but was not able to find any. Any thoughts?

Have a couple of questions that may be of use to you:
Is there any benefit to encrypting twice using pgp?
Is encrypting twice good or bad?
https://crypto.stackexchange.com/questions/779/hashing-or-encrypting-twice-to-increase-security
https://crypto.stackexchange.com/questions/5382/is-it-safer-to-encrypt-twice-with-rsa
https://crypto.stackexchange.com/questions/2314/does-encrypting-twice-using-the-same-block-cipher-produce-a-security-weakness
General idea seems to be this point:
Well, think about it this way. If breaking one encryption with brute
force will take longer than the lifetime of the universe, are you any
safer with an encryption scheme that will take twice the lifetime of
the universe? No. The first encryption cannot be broken. Adding a
second encryption just adds computation overhead with no real benefit. - mikeazo
I would advise asking this question in https://crypto.stackexchange.com/, they may give you more detailed information on the topic.

There's a simple rule in cryptography. All the security should be in the key. Based on that there should be no additional security in encrypting twice because all your security should be in the choice and storage of your key.
Now that being said... you could get some additional security if you make wrong choices. For example say you encrypt the first time with ECB mode (Electronic Code book), because of the way that mode works (by encrypting each block of your plaintext separately), you could get extra security by encrypting a second time in a more secure mode (CBC or CTR). But... you could just as well encrypt in CBC mode the first time around.
You could encrypt the first time with an insecure algorithm (such as DES) and encrypt a second time with a much better algorithm (such as AES).
But these situations are hypothetical and would require you to intentionally make mistakes or be extremely negligent. If you use AES (Rijandael) twice in a secure mode like CTR or CBC then you will not get any additional security from encrypting twice so long as your key is stored securly and selected in a secure manner.

Related

Simple Encrypt/Decrypt for Database storage

I have been looking for a simple encryption/decryption class for storing information in the database. Trouble is I have no clue what I'm looking at half the time, so I really don't know if what I find is really all that worth implementing for what I need, whether it be over-complex or too easy to crack.
I have brain stormed about it for a bit, my first thought-train leading to a simple "switch, add, multiply" key for the ACII Values, but I think that wouldn't really be worth it after seeing what encryption classes actually are.
Essentially I'm looking for a key that encrypts any and all data (including table and column names) on storage, and decrypts on withdrawal. But like I said, doesn't need to be too complex, but if someone does want to access the data, they have to earn it haha.
Can anyone suggest a good link/provide a simple class for what I'm looking for? It could possibly be something I have found before, but like I said, I haven't the faintest as to what I'm looking at half the time
Thanks in advance!
Pre-emptive Edit I know some Databases have their own encrypt/decrypt methods, but I figure this is the easiest way to implement it because I will be working will multiple different database programs.
AES 256 is (while potentially overkill) a very secure encryption algorithm. Microsoft provides an implementation in System.Security.Cryptography and the example at MSDN is a great place to get started.
I've used this for database encryption and it works just fine.
Since you said you are new to encryption, I will try to touch on what encryption does, and doesn't do for you. Encryption takes normal data (ie. ("My private string")) and turns it into random data (bunch of bytes), only reversible by knowing the private key (in AES 256). Data, since it is different between cells, and likely private/important information is a good thing to encrypt.
Your database schema is constant, so encryption is only minimally useful here. The difference between calling a table "Names" and "A" and "oiaeoriuojdklfjsad" (this last is an example "encryption") is minimal. This is what is meant by "security by obfuscation". You could argue that choosing a random name is slightly more secure than a descriptive one, but it is really just going to confuse you when you try to use it, and the real "gold" a hacker will want is the data anyways. Knowing what kind of data it is isn't really going to help if it's going up against a good encryption algorithm.

Best practice of Hashing passwords

I would like to know which method to use to store passwords in database. I have implemented it using MD5 but according to some posts SHA1 is more secure. Is there any other method which is more secure?
Please help me finding out a best method to secure passwords.
Sure SHA1 is more secure that MD5, but for most purposes it is not secure enough.
You will probably find useful the video How NOT to Store Passwords by Computerphile - 9 minutes and 24 seconds long.
You must realize that there is much to cover when it comes to authentication and access control, so having a good hashing scheme is not enough.
On storing passwords.
As you already know, you don't store the password. In fact, when it comes to storing passwords, in general terms you want to store salted hashes of the passwords, using a modern algorithm optimized for this purpose. For the salt it is considered ok to store it alongside to the hash, for the salt value use a random value as long as possible.
Note: When generating random value for security purposes, use a cryptographic secure generator (such as a subclass of RandomNumberGenerator for .NET - example). This random number generator are designed to be hard to predict. While standard random number generator are meant to be repeatable (That is with System.Random all you need is the seed to generate all the values, and to guess the seed all you need is enough consecutive values generated with the same seed).
Also note: Most hashes are optimized to be fast to calculate, in that category falls both MD5 and SHA1. You should choose one that is not that fast, so that the attack will take a reasonable amount of time to compute the hashes when trying to crack your passwords.
One such algorithm is BCrypt - others include Scrypt and PBKDF2 - on using BCrypt from C# you will find the article Use BCrypt to Hash Your Passwords: Example for C# and SQL Server useful. If you can't resource to BCrypt or similar algorithm, you should atleast use a variant of SHA2 (SHA256, SHA512 and so on).
Addendum: You can use the class HMACSHA256 which is available in the BLC as a key derivation function, pass your salt as key. This is preferible to appending or prepending the salt (which could fall to Length extension attacks). That is, if you use HMAC, and your hash algorithm is vulerable to Length extension attacks (known or to be discovered), your system is till secure. MD5, SHA1 and SHA2 as suceptible to this kind of attack. SHA3 is not. Sadly SHA3 is not included in the BLC (no, it is not SHA384), you can get it from Multiformats.Hash or HashLib. I have to mention that SHA3 is also designed to be fast when implemented in hardware. And remember, for passwords an slow hash is better.
Addendum: Argon2
As it was pointed a year ago this answer should be updated to mention of Argon2. I did write the original answer before that existed.
At the time, I had not found an implementation for C# that I was willing to recommend. Since this answer was brought to my attention, I had another look, and that is no longer the case.
You can use Isopoh.Cryptography.Argon2 which has fully managed code (it is not a C# binding for a C++ implementation, but full C# code), works on all major platforms and there are Nugets available.
Notes:
Use Argon2Version.Nineteen. This is Argon2 v.1.3 (Nineteen = 0x13) which fixes known vulnerabilities.
Use Argon2Type.DataDependentAddressin (Argon2d), or use Argon2Type.DataIndependentAddressing (Argon2i) with TimeCost >= 10. Argon2d is in theory vulnerable to side channel attacks, as such it is not recommended for code that runs on client machines. Isopoh.Cryptography.Argon2 mitigates this by using OS calls to prevent sensitive memory to be moved to virtual memory/pagefile/swap and zero it as soon as possible. On the other hand Argon2i has a Time-memory tradeoff vulnerability, which allows to compute the hashes faster by using more memory. The paper Towards Practical Attacks on Argon2i and Balloon Hashing shows that you need 10 iterations/passes to make the exploit inefficient, even in Argon2 v.1.3.
Here are some recommended reading:
Speed Hashing
You're Probably Storing Passwords Incorrectly
Everything you ever wanted to know about building a secure password reset feature
The definitive guide to form based website authentication
OWASP's Password Storage Cheat Sheet
OWASP's Forgot Password Cheat Sheet
Also the video: Crypto is Back! - Google Tech Talk - August 5, 2009 - 54 minutes and 32 seconds long.
On recovering a password.
First off: don't. The point of the password recovery option is not to recover the password, but to recover access to the application. So... how do you recover access to the application?
I'm glad you ask. What you need is an alternative way to verify the identity of the user. This could be a second factor authentication (anything from security question to using a hardware key generator). Yet, what is often done is to resource on third party, such as mail.
So, you want to know if the user is the owner of the email (or cellphone, or whatever) the user has previouly claim to own. In order to do so you send a code (often refered as token or cookie) to that email (or whatever). This must be a random generated code with a cryptographic secure generator so that nobody else - except the owner of that email (or whatever) - will be able to know what that code is.
Now, if the user presents to your application that code, you are almost sure it is the right user.
Almost because: emails (or whatever) could has been stored in an unsecure location. To mitigate that, you want to put a time limit on your code (cookie or token). Also, if a code has been used, it should NOT work again. And for extra security you could resource to a CAPTCHA, to ensure this code doesn't come from a bot that just got lucky.
For more on this topic (this links are also presented above):
Everything you ever wanted to know about building a secure password reset feature
OWASP's Forgot Password Cheat Sheet
SHA1 has less vulnerabilities than MD5. It's a newer algorithm that utilizes more bits and requires more processing to "crack." You can view most of the mainstream hash algorithms and their known vulnerabilities here: http://en.wikipedia.org/wiki/Cryptographic_hash_function
As someone already commented, definitely make sure you add "salt" to your password hash to further obscure any possible pattern.

C# encryption key discussion

I am writing a .net application and want to use a supper strong encryption key by using the unicode characters to make it hard for the hackers to hack the code. The encryption key would be any characters from the http://www.unicode.org.
For example my encryption key could லูᇉޒۻڃxxxxxxxxxxxx + couple hundred characters which is very difficult for the computer to predict my code. I think the unicode has more than 95,000 characters.
I am wondering if there is any data corruption because of these complex characters. Of course I have to check the decrypt data to make sure the code can decrypt before I save the information to the database. I have tested my code for more than 10 millions times to see how reliable and it run pretty good.
Any thoughts guys?
Encryption is very very difficult to do. More likely than not, your approach will be very insecure.
The strength of an algorithm is more than just a key size. I'd wager that DES with a 56-bit key is more "secure" than probably any home made cipher.
The AES process was a multiple year effort of every cryptographer in the world, multiple government agencies, support from Microsoft, RSA (among others), various open source projects, and millions of dollars. Even after all that, we still find new attacks against AES.
What are your requirements? You should use established protocols and algorims. If you say what your trying to do, we can give better advice.

best encryption method

What is the most standard encryption technique used in sql server for asp.net c# enterprise level application? . i am talking with respect to standards like md5 or sh1 etc, hashing
What you describe is called hashing, not encryption.
I think you can use some form of SHA-2, possibly after concatenating with a 'salt' string. Most common platforms provide built-in functions for such hashing algorithms. Details: http://en.wikipedia.org/wiki/SHA-2
Enterprise applications don't store passwords. They use NTLM/Kerberos integrated security and rely on impersonation and constrained delegation to secure access end-to-end.
Hashing and/or encryption as a means to protect against accidental media loss is much better served with Transparent Data Encryption, which encrypts an entire database transparently.
Password hashing against a compromised host disclosure of passwords which opens the potential of password reuse on unrelated sites can use built-in hashing functions like HashBytes. As long as the hash is properly used (correctly salted). But with a compromised host the battle is already lost.
I've generally found Md5 (with salt) to be quite common.
However
I've seen time and time again, where the login page(s) are done via standard http!
This is a bigger concern then someone hacking into web-server/ SQL box and getting hold of the passwords.
Read about the Cookiemonster Attack for more information regarding 'Man in the Middle' type security issues.

Better hashing than SHA1

I'm working on an application and I need to store the users password, so I'm thinking I'll store it in the current-user class of the registry, but I also want to hash it for the obvious reason, and I've seen news items that state that SHA1 has been cracked, is there a better (uncracked) hashing algorithm available in the "standard" system or .net?
SHA1 is not encryption, it's a cryptographic hash function. And yes it has been broken, which means it's possible to generate collisions faster than a brute force method. The SHA2 family has not been broken.
But I would advise to use a custom seed per entry so that a rainbow table could not be used for trying out passwords. If you're using the SQL Membership provider the password format "Hashed" already uses a different seed for each user.
More information about seeding your hash can be found in the article What You Need To Know About Secure Password Schemes by Thomas Ptacek.
As you say in your comment, SHA1 is a hash algorithm, not encryption. It is a one-way function that, even if it is broken, does not allow the password to be retrieved.
If you want stronger hash functions that are already in .NET, look at the SHA2 family - SHA256, SHA384, SHA512. (SHA224 also exists, but isn't implemented in the System.Security.Cryptography namespace.)
The collision attacks on SHA1 are not practically exploitable yet, but you are right to be looking ahead. NIST is currently running a selection process for SHA3 in the light of these attacks, but this is a few years from completion and commercial acceptance. SHA2 on the other hand is an existing family of algorithms that are standardised by NIST and are not subject to the attacks that have been successful against MD5 and SHA1.
What you need to do is salt your passwords. Here is some actual sample code in C# that uses SHA1 and salting.
The problem with SHA1 "being cracked" is all basic possible combinations have been pre-calculated, however salting makes your password nonbasic (it is still vulnerable to a brute force if it is weak or easily guessable but it kills rainbow tables)
Hash algorithms have been showing some signs of weakness as of late, which is why NIST has offered up a hashing contest much like they had an encryption contest which crowned Rijndael as the new AES.
I personally like what MD6 has to offer, as it is being spearheaded by Ron Rivest, who has been in the cryptography space for over three decades. MD6 has been withdrawn, so I suggest some of the stronger candidates in Round 2 in my humble opinion are Keccak, Blue Midnight Wish, and Fugue.
From there, definitely use good practices such as salting.
Yes you can use SHA512, just remember how long the actual hash is. You can always add extra security by salting the hash results as well.
SHA512("The quick brown fox jumps over the lazy dog") =
07e547d9 586f6a73 f73fbac0 435ed769 51218fb7 d0c8d788 a309d785 436bbb64
2e93a252 a954f239 12547d1e 8a3b5ed6 e1bfd709 7821233f a0538f3d b854fee6
If you want to look into other Hashing algorythms, here's a short list.
5 days too late but you could try this highly secure encryption function:
uint64_t highly_secure_encrypt(char* password) {
sleep(1);
return 0;
}
No way you're getting the passwords back from that.
Now, onto serious matters. If you don't already know the answer to your question you shouldn't be designing security systems.
If you're storing the password in the current-user section of the registry then the only people who can access it (under normal circumstances) are the user and the administrator. I'd trust (somewhat) the current-user section of the registry and use the standard password hashing mechanisms that the OS provides.
Jeff Atwood's "Rainbow Hash Cracking" describes hashes and password storage at a good beginner detail, and Thomas Ptacek's "Enough With the Rainbow Tables: What You Need to Know About Secure Password Schemes" goes on to tell you why you should not try and do it yourself usually.
Choosing a good hash function is less than 1% of the battle. If an attacker can run you hash function millions of times a second then (s)he can test millions of combinations a second. What you need is a slow, tunable secure hash. That's not something that is easy to come by and SHA*, MD5, etc are designed to be bloody fast since they're meant to be used over files and chunks of files usually, where speed is king.
I'd recommend reading up more, since the answers are out there and very easy to find.

Categories

Resources