开源日报 每天推荐一个 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/