開源日報 每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,堅持閱讀《開源日報》,保持每日學習的好習慣。
今日推薦開源項目:《RapidJSON》
今日推薦英文原文:《Salting and Hashing Explained》

今日推薦開源項目:《RapidJSON》傳送門:項目鏈接
推薦理由:該項目是基於 C++ 的 JSON 解析/生成器,對 JSON 格式的文件提供高效分析,並提供 SAX 及 DOM 風格的 API。
今日推薦英文原文:《Salting and Hashing Explained》作者:Rakshit Dwivedi
原文鏈接:https://medium.com/better-programming/salting-and-hashing-explained-b76f5af83554
推薦理由:給哈希密碼加點鹽。

Salting and Hashing Explained

Learn how hashing and salt protect user data as well as how to use them in Node.js

(Photo by Jason Tuinstra on Unsplash.)
User information and data are highly sensitive information that must be secure. Therefore, it is highly necessary that robust measures are taken to protect it at all costs. Furthermore, passwords should never be stored as plain text on a database. They should be strongly encrypted to avoid chaos among users.

In this article, we will discuss how salt and hashing work to encrypt user passwords as well as the risks inherent with storing sensitive user information in plain text.

How Hashing Works

A hashing algorithm (MD5 hash) grabs the user-input password and converts it into an indecipherable string. This is called a hashed password. Anyone who launches an attack on your database cannot make sense of it because hashing works only one way. This means that once a password is hashed, you can』t go back the other way around to convert it into plain text again. And for this reason, hashing user passwords is a crucial task that should be done when designing the back end.

Here is an example of how a password is hashed:

If you want to play around yourself to see how hashing generates a new string, head to MD5 Hash Generator.

Why Hashing Is Not Sufficient

When you look at the example above, you may notice that the hashed string doesn't make sense to you at all. If you think that just hashing your password would suffice, you are wrong. The reason why is a hashing algorithm does not inherently produce a unique string for the same password text each time it』s received. In other words, suppose your password looks like the example above (Password@1234). Each time the algorithm receives the same input string, it will always produce the same hash string (i.e. 0F1BA603C1A843A3D02D6C5038D8E959). This is not ideal because a hacker can launch a rainbow attack on your database to crack the passwords stored inside.

Let me tell you a little about rainbow table attacks as well.

Rainbow table attack

An attacker can use a pre-built table of passwords mapped with their respective hash strings. Then they will use randomly hashed strings to run it against the table database. If a match is found, they can simply look at the password that was used to create the hash and map it to crack the password. For this reason, it』s not suggested to use names, birthdates, or commonly used strings such as 「password,」 「12345678,」 and so on.

Salt With Hashing

Our problem with hashing is fixed with a simple solution: using salt. Salt is a randomly generated, fixed-length value that is designed to be unique with each user password. Salt is appended with the current password string and fed into the hashing system to produce a newly hashed result every time a user creates a password. This means that if you and I have the same password, our hashed strings would be different. And since rainbow table attacks heavily depend on finding a match, it would render them useless.

The bcrypt library, which creates both salt and hashed data with strong cryptography algorithms backing it, is great for this purpose.

How to Add Salt and Hash in Node

Installing bcrypt

Run the following command in your terminal:

npm install bcrypt

Salting and hashing user password

const bcrypt = require('bcrypt');

const userSchema = new mongoose.Schema({
  email: {
    type: String,
    unique: true,
    required: true
  },
    passwrod: {
        type: String,
        required: true
    }
});

userSchema.pre('save', function(next) {
    const user = this;
    if (!user.isModified('password')) {
        return next();
    }

    bcrypt.genSalt(10, (err, salt) => {
        if(err) {
            return next(err);
        }

        bcrypt.hash(user.password, salt, (err, hash) => {
            if(err) {
                return next(err);
            }
            user.password = hash;
            next();
        });
    });
});
Here』s an example of how a user password with some other information will be stored in the database:

Conclusion

It』s always recommended to encrypt the sensitive information of each user on the database. When you are designing the back-end system, always keep in mind the risks that come together with any action. Hence, some software companies hire ethical hackers to breach their network security to find loopholes in the system. From a programmer』s perspective, it』s a good practice to test your code before deploying it to mainstream users.


下載開源日報APP:https://openingsource.org/2579/
加入我們:https://openingsource.org/about/join/
關注我們:https://openingsource.org/about/love/