Use strong encryption and hashing algorithms in Java
Tags: java, security, encryption, hashing
Published: 2019-12-24 13:24:58

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](https://github.com/google/tink).

```xml
<dependency>
   <groupId>com.google.crypto.tink</groupId>
   <artifactId>tink</artifactId>
   <version>1.3.0-rc3</version>
</dependency>
```

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.

```java
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);
}
```

##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](https://snyk.io/blog/10-java-security-best-practices/) and the easy [printable one-pager](https://snyk.io/blog/10-java-security-best-practices/) available