What is the difference between encryption, hashing and salting?
Tags: encryption, hashing, salting, security
Published: 2022-02-26 11:52:37

# Introduction

When we discuss about user authentication in an application, consequently, we already think about information security and how user data will be used and stored in the application.

Some security concepts and techniques are used such as encryption, hashing and salting to obtain a higher level of security, but each one has its purpose and I will introduce the concepts, differences and how it is used in practice in this article.

But what is the difference and when to apply each one?



# Concept

The concepts and techniques are different so I will explain each one so you can use it in your application.


## Encryption

Encryption is the process of converting data using an access key with the possibility of recovering it. Encryption is a two-way (bidirectional) process, that is, it is possible to encrypt data and decrypt the same data using the same access key. There are some types of encryption known like *AES (Advanced Encryption Standard)*, *RSA (Rivest-Shamir-Adleman)*, among others.


## Hashing

Hashing is the process of converting data without needing to retrieve it, and hash types have the same length regardless of the converted data. Hashing is a one-way (unidirectional) process, that is, data can be encrypted but not decrypted. There are some types of hashing known like *MD5*, *SHA1*, *SHA256*, *SHA512*, among others. 


## Salting

Salting is the process of adding random data when converting data using hashing. There are some types of salting known as *scrypt*, *bcrypt*, *Argon2*, among others. This process is often used when storing passwords in the database. 



# Practice

The examples used in practice will be developed using [Node.js](https://nodejs.org/) and the [crypto](https://nodejs.org/api/crypto.html) module. 


## Encryption

A practical example of encryption use is in the communication between two applications where the application A encrypts the data and sends this encrypted data to the application B, where this communication can be done by a database or by an HTTP request, and the application B decrypts the data for use. In this example, the access key must be in applications A and B.

There are two classes in the crypto module called [Cipher](https://nodejs.org/api/crypto.html#class-cipher) and [Decipher](https://nodejs.org/api/crypto.html#class-decipher) that we are going to use in the example.

**1.** Create the application folder.

```powershell
mkdir nodejs-encryption
cd nodejs-encryption
```

**2.** Create the file `package.json`. The option `-y` allows the file to be created without the questions, such as application name, version, among others.

```powershell
npm init -y
```

**3.** Create the folder `src` and create the file `index.js` inside the folder `src`.

```powershell
mkdir src
touch src/index.js
```

**4.** Add the content below in the file `src/index.js`.

```javascript
const { createCipheriv, createDecipheriv } = require('crypto');

const algorithm = 'aes-256-cbc';
const key = 'REtgV24bDB7xQYoMuypiBASMEaJbc59n';
const iv = '8d2bc3f0f69426fc';

const encrypt = (data) => {
  const cipher = createCipheriv(algorithm, key, iv);
  let crypted = cipher.update(data, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return crypted;
};

const decrypt = (data) => {
  const decipher = createDecipheriv(algorithm, key, iv);
  let decrypted = decipher.update(data, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
};

const data = 'Some data plain';

const dataEncrypt = encrypt(data);
const dataDecrypt = decrypt(dataEncrypt);

console.log(`Data=[${data}]`);
console.log(`Data encrypted=[${dataEncrypt}]`);
console.log(`Data decrypted=[${dataDecrypt}]`);
```

**Notes:**

* `createCipheriv`: This method creates and returns an object of type Cipher. The arguments are:
 * `algorithm`: AES (Advanced Encryption Standard) algorithm type of encryption.
 * `key`: Access key. The length of the key depends on the type of algorithm that will be used. 
 * `iv`: Any value that is used once on the sender and receiver side. The length of the iv depends on the type of algorithm that will be used.
* `createDecipheriv`: This method creates and returns an object of type Decipher. The arguments are:
 * `algorithm`: AES (Advanced Encryption Standard) algorithm type of decryption.
 * `key`: Access key. The length of the key depends on the type of algorithm that will be used.
 * `iv`: Any value that is used once on the sender and receiver side. The length of the iv depends on the type of algorithm that will be used.
* `update`: This method updates the encryption or decryption with the data. The arguments are:
 * `data`: Data that will be encrypted or decrypted.
 * `inputEncoding`: Data input encoding.
 * `outputEncoding`: Data output encoding.
* `final`: This method returns encrypted or decrypted data. A string is returned when informed the encoding, otherwise, a Buffer will be returned.

**5.** Run the application with the command below.

```powershell
node src/index.js 
Data=[Some data plain]
Data crypted=[4ee8b9fd43c94019edebafc2d6374c82]
Data decrypted=[Some data plain]
```

**Notes:**

* The *Some data plain* data was passed to the `encrypt` method and this method encrypted the data generating the value `4ee8b9fd43c94019edebafc2d6374c82`.
* The value `4ee8b9fd43c94019edebafc2d6374c82` was passed to the `decrypt` method and this method decrypted the value generating the data *Some data plain*.

**6.** Ready! We created an example of data encryption and decryption.

The application repository is available at [https://github.com/rodrigokamada/nodejs-encryption](https://github.com/rodrigokamada/nodejs-encryption).


## Hashing

A practical example of hashing use is storing a user's password in a database by applying a hash type. Whenever the user enters the password on the sign in page, the password hash is compared to the hash stored in the database.

There is a class in the crypto module called [Hash](https://nodejs.org/api/crypto.html#class-hash) that we are going to use in the example.

**1.** Create the application folder.

```powershell
mkdir nodejs-hashing
cd nodejs-hashing
```

**2.** Create the file `package.json`. The option `-y` allows the file to be created without the questions, such as application name, version, among others.

```powershell
npm init -y
```

**3.** Create the folder `src` and create the file `index.js` inside the folder `src`.

```powershell
mkdir src
touch src/index.js
```

**4.** Add the content below in the file `src/index.js`.

```javascript
const { createHash } = require('crypto');

const crypt = (data) => {
  const hash = createHash('sha256');
  hash.update(data);
  return hash.digest('hex');
};

const data = 'Some data plain';

const dataCrypt = crypt(data);

console.log(`Data=[${data}]`);
console.log(`Data crypted=[${dataCrypt}]`);
```

**Notes:**

* `createHash`: This method creates and returns an object of type Hash. The arguments are:
 * `algorithm`: Algorithm type supported by the OpenSSL version.
* `update`: This method updates the hash with the data. The arguments are:
 * `data`: Data that will be converted to hash.
* `digest`: This method returns data converted to hash. A string is returned when informed the encoding, otherwise, a Buffer will be returned.

**5.** Run the application with the command below.

```powershell
node src/index.js 
Data=[Some data plain]
Data crypted=[039ee8ef355ee07c345fe6feaa22d6c1bf34ac91eb45abb80602c59deb5d34e7]
```

**Note:**

* The *Some data plain* data was passed to the `crypt` method and this method converted the data generating the value `039ee8ef355ee07c345fe6feaa22d6c1bf34ac91eb45abb80602c59deb5d34e7`.

**6.** Ready! We created an example to convert the data to hash.

The application repository is available at [https://github.com/rodrigokamada/nodejs-hashing](https://github.com/rodrigokamada/nodejs-hashing).


## Salting

A practical example of salting use is in storing the user's password in a database where random data is added with the password and then a type of hash is applied.

There is a method in the crypto module called [scrypt](https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback) that we are going to use in the example.

**1.** Create the application folder.

```powershell
mkdir nodejs-salting
cd nodejs-salting
```

**2.** Create the file `package.json`. The option `-y` allows the file to be created without the questions, such as application name, version, among others.

```powershell
npm init -y
```

**3.** Create the folder `src` and create the file `index.js` inside the folder `src`.

```powershell
mkdir src
touch src/index.js
```

**4.** Add the content below in the file `src/index.js`.

```javascript
const { scryptSync } = require('crypto');

const salt = 'some-salt';
const keyLength = 64;

const crypt = (data) => {
  const derivedKey = scryptSync(data, salt, keyLength);
  return derivedKey.toString('hex');
};

const data = 'Some data plain';

const dataCrypt = crypt(data);

console.log(`Data=[${data}]`);
console.log(`Data crypted=[${dataCrypt}]`);
```

**Notes:**

* `scryptSync`: This method converts the data to hash. The arguments are:
 * `data`: Data that will be converted to hash.
 * `salt`: A random data.
 * `keyLength`: Key length.
* `toString`: This method converts the type from Buffer to string.

**5.** Run the application with the command below.

```powershell
node src/index.js 
Data=[Some data plain]
Data crypted=[2b57498b290aa7d31741dc71b60f59f9b5f59431c842500502704f0d7e7b8204293b13bcb8ee54ef2f4f8c99711f27c42144d1c46d5c44362bd5a6748bf7a1bc]
```

**Note:**

* The *Some data plain* data was passed to the `crypt` method and this method converted the data generating the value `2b57498b290aa7d31741dc71b60f59f9b5f59431c842500502704f0d7e7b8204293b13bcb8ee54ef2f4f8c99711f27c42144d1c46d5c44362bd5a6748bf7a1bc`.

**6.** Ready! We created an example to convert the data to hash using a salt.

The application repository is available at [https://github.com/rodrigokamada/nodejs-salting](https://github.com/rodrigokamada/nodejs-salting).



# Conclusion

After presenting the concepts and the use in the practice of encryption, hashing and salting, even if everything is related to security, each one has its purpose and to reinforce all this:

* **Encryption** is a two-way process making it possible to encrypt and decrypt data used in the communication between two applications. 

* **Hashing** is a one-way process making it possible the authenticity and integrity of the data used in storing the user's password.

* **Salting** is the process of adding random data to the hashing also used in storing the user's password.

Understanding the security concepts and implementing the security techniques are very important to keep your application or system secure.



This tutorial was posted on my [blog](https://rodrigo.kamada.com.br/blog/qual-e-a-diferenca-entre-criptografia-hashing-e-salting) in portuguese.