DEV Community

Cover image for Use strong encryption and hashing algorithms in Java
Brian Vermeer πŸ§‘πŸΌβ€πŸŽ“πŸ§‘πŸΌβ€πŸ’»
Brian Vermeer πŸ§‘πŸΌβ€πŸŽ“πŸ§‘πŸΌβ€πŸ’»

Posted on β€’ Edited on

3 1

Use strong encryption and hashing algorithms in Java

If you need to store sensitive data in your system, you have to be sure that you have proper encryption in place. First of all you need to decide what kind of encryption you need β€”for instance, symmetric or asymmetric. Also, you need to choose how secure it needs to be. Stronger encryption takes more time and consumes more CPU. The most important part is that you don’t need to implement the encryption algorithms yourself. Encryption is hard and a trusted library solves encryption for you.

If, for instance, we want to encrypt something like credit card details, we probably need a symmetric algorithm, because we need to be able to retrieve the original number. Say we use the Advanced Encryption Standard (AES), which is currently the standard symmetric encryption algorithm for US federal organizations. To encrypt and decrypt, there is no reason to deep-dive into into low level Java crypto. We recommend that you use a library that does the heavy lifting for you. For example, Google Tink.

<dependency>
   <groupId>com.google.crypto.tink</groupId>
   <artifactId>tink</artifactId>
   <version>1.3.0-rc3</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Below, there’s a short example of how to use Authenticated Encryption with Associated Data (AEAD) with AES. This allows us to encrypt plaintext and provide associated data that should be authenticated but not encrypted.

private void run() throws GeneralSecurityException {
   AeadConfig.register();
   KeysetHandle keysetHandle = KeysetHandle.generateNew(AeadKeyTemplates.AES256_GCM);

   String plaintext = "I want to break free!";
   String aad = "Queen";

   Aead aead = keysetHandle.getPrimitive(Aead.class);
   byte[] ciphertext = aead.encrypt(plaintext.getBytes(), aad.getBytes());
   String encr = Base64.getEncoder().encodeToString(ciphertext);
   System.out.println(encr);

   byte[] decrypted = aead.decrypt(Base64.getDecoder().decode(encr), aad.getBytes());
   String decr = new String(decrypted);
   System.out.println(decr);
}
Enter fullscreen mode Exit fullscreen mode

Password encryption

For passwords, it is safer to use one-way encryptions as we don’t need to retrieve the original passwords but just match the hashes. BCrypt and, his succor, SCrypt are the most suitable for this job. Both are cryptographic hashes (one-way functions) and computationally difficult algorithms that consume a lot of time. This is exactly what you want, because brute force attacks take ages this way.

Spring security provides excellent support for a wide variety of algorithms. Try using the SCryptPasswordEncoder and BCryptPasswordEncoder that Spring Security tool 5 provides for the purpose of password hashing

What is a strong encryption algorithm today, may be a weak algorithm a year from now. Therefore, encryption needs to be reviewed regularly to make sure you use the right algorithm for the job. Use vetted security libraries for these tasks and keep your libraries up to date.

This was just 1 of 10 Java security best practices. Take a look at the full 10 and the easy printable one-pager available

Image of Stellar post

πŸš€ Stellar Dev Diaries Series: Episode 1 is LIVE!

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

Top comments (3)

Collapse
 
likelocusts profile image
LikeLocusts β€’

Please mind the terminology. You wrote about password encryption, while actually talking about hashing.
There is a big difference, especially concerning secure password storage.
Using encryption you could always reverse the process and retrieve the clear text password, while a hashed password can't be reversed, only validated against the actual password.

"For passwords, it is safer to use asymmetric encryptions as we don’t need to retrieve the original passwords..."

Well asymmetric encryption let's you retrieve the password just like symmetric encryption, you only need more keys.
It has nothing to do with hashing.

Collapse
 
brianverm profile image
Brian Vermeer πŸ§‘πŸΌβ€πŸŽ“πŸ§‘πŸΌβ€πŸ’» β€’

Thanks for pointing this out. By mistake I used the term asymmetric instead of one-way encryption.
Will change it right away.

Collapse
 
elmuerte profile image
Michiel Hendriks β€’

Two things concerning password encryption:

  1. Always make the effort parameters a configuration setting. You want to change those values in the future. For BCrypt it is just a weight parameter, which at this point should be something like 11 or 12. The weight is exponential. You might want to benchmark it. Something between 0.25 and 0.50 seconds is a nice performance without annoying legitimate users too much. For SCrypt there are two parameters, CPU and memory cost, which would be 214 and 8 respectively.

  2. BCrypt and SCrypt are vastly different algorithms with vastly different characteristics. BCrypt is battle-tested, it has been around a long time, and still holds up. It is also properly understood by experts. SCrypt is much newer, theoretically it should be better, when configured correctly. As it is much newer, it has not received the same amount of scrutiny by experts. Additionally, performance of SCrypt in Java is quite bad compared to what can be achieved when using special CPU instructions.

It might be best to use BCrypt in Java. Spring's JavaDoc for Scrypt also refers to this interesting article about BCrypt vs. SCrypt.

Or maybe make use of DelegatingPasswordEncoder and even make that part of your system configurable.

Retry later
πŸ‘‹ Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay