Search code examples
javaencryptionpassword-encryption

Multiple Encryption Technique in Java


Is it safe to encrypt an already encrypted data using another algorithm?

For instance, I have encrypted a password using "PBKDF2WithHmacSHA1".

Now I want to further encrypt it using "SHA512" (since it is considered better than "SHA1")

Will that in any way weaken my encryption?

Also, should I reverse the encrypted password to increase security?

Even if "PBKDF2WithHmacSHA1" is enough, I would rather have extra layers of protection. That is why I have been thinking of multiple encryption. However, I am not intending to use third-party options such as BouncyCastle at present.

It would be helpful if you are Java specific.

Thank you !


Solution

  • So a few things...

    1: "Is it safe to encrypt an already encrypted data using another algorithm"

    Answer: yes. It will require two algorithms to decrypt, presumably neither of which the attacker knows (or in what order, etc.), so it is safe. It will not damage your data.

    2: " I have encrypted a password using "PBKDF2WithHmacSHA1"."

    Comment: Wrong. You have ENCRYPTED nothing. What you have done is HASHED your password. The critical difference is that a HASH is a fixed-length representation of a piece of data of arbitrary length. This means that the hash of "hello" will be exactly the same length (but different content) of "this is a longer phrase" (this assumes you use the same algorithm for both, which you are). Assuming the hash algorithm is designed correctly, it should be impossible to reverse engineer and get your original data back. Encryption, on the other hand, takes in data of arbitrary length, and spits out "random" data of similar length. With encryption, it is possible to get your original data back.

    So, to be clear, you are hashing, not encrypting. This will be an important difference in a moment.

    3: Now I want to further encrypt it using "SHA512" (since it is considered better than "SHA1") Will that in any way weaken my encryption ?

    Answer: As already stated, you're hashing, not encrypting your password. This means that as soon as your PBKDF2WithHmacSHA1 algorithm finishes, you will have a string with 2^160 possible combinations (source: PBKDF2WithHmacSHA512 Vs. PBKDF2WithHmacSHA1). This means that you have created a FINITE (although admittedly large) set of possible values that you can then feed into PBKDF2WithHmacSHA512, or simple SHA512 (whichever).

    Here's the important part. Remember, hashing provides a string that is a REPRESENTATIVE of the data. Since you have already generated a hash with a result space of 2^160 possible entries, running that through a more powerful hashing algorithm will NOT significantly increase your security.

    4: "I am not intending to use third-party options such as BouncyCastle at present."

    Comment: I'm not exactly sure what you mean by this, but I'll provide a word of warning. One of the biggest rules of encryption is: don't do it yourself. DO NOT write your own algorithm. Don't even write your own implementation of a standard algorithm (except as an academic exercise or something, for example). Instead, use a library (either one included with JAVA or a third party) that is KNOWN to be properly designed and functional.

    5: Everything else: Extra layers of protection is a good thing. reversing the password is one such thing you can do; another popular (and widely used) method is to introduce a SALT. This is just a word or phrase (typically stored plaintext) that you use in your function. For instance, if you were hashing "hello", you could use a salt like "helloSALT", "ShelloALT", "helSAloLT", etc. It is simply extra data to introduce into the pre-hashed data to make it more complicated. Ideally, only your program would know how the salt got used, and so breaking the password would be much more difficult. EDIT: As Perseids pointed out below, a SALT is different per-password. You can also introduce a PEPPER (yes, salt and pepper), which is essentially the same except that the PEPPER is constant throughout your program.

    HOWEVER!

    With how fast computers these days are, the biggest problem is COMPUTATION TIME. Specifically, with how SMALL it is. A SHA1, or even a SHA512 hash can be generated VERY quickly, which allows computers to generate millions of them per second, allowing them some success at BRUTE FORCING your password (a bad thing). So, what you ideally want is an algorithm that takes a "long" time to generate (by "long" I mean maybe 1 - 10ms....still very fast by human standards, but very slow by computer standards). For example, if your hash took 10ms to generate, you could only calculate 100 of them per second....not millions.

    Enter BCrypt. Like SHA512, this is a hashing algorithm. (It's also the name of a file encryption utility, try not to confuse the two). BCrypt is an ADAPTIVE algorithm. It is designed so that you can make the hashes more complicated as computers get more powerful. Rather than go into detail, I'll simply redirect you to this online bcrypt generator: https://www.dailycred.com/blog/12/bcrypt-calculator

    For reference, with 4 iterations selected, the hash generated nearly instantly, but with 12 iterations selected, the hash took around 2 full seconds to generate - a VERY long time to generate a single password. The demo only goes up to 12, but bcrypt supports 31. (This number is according to the website, and that number could be arbitrary, and mean something else. The point is, with bcrypt you can configure it to take longer to generate a hash - The attacker would not only need more time to generate the hash, but they would need to know HOW MANY REPETITIONS to target...which is yet another layer of security).