哈希密码存储为 BSON BinData 类型

hash password stored as BSON BinData Type

我有这个脚本,它是一种将用户添加到 mongo 数据库的临时方法。

操作正常进行,但为密码生成的散列存储为 BSON Binary Data (a.k.a BinData)

#!/usr/bin/python3

import bcrypt
from getpass import getpass
from pymongo import MongoClient

def connect():
    db_user = "mongo"
    db_pass = "mongo"
    db_addr = "127.0.0.1:27017"
    uri = "mongodb://{0}:{1}@{2}".format(db_user,db_pass,db_addr)
    client = MongoClient(uri,serverSelectionTimeoutMS=6000)
    return client

try:
    user_data = {}
    user_data["Name"]     = input("Full Name:  ")
    user_data["Sector"]   = input("Sector:     ")
    user_data["Email"]    = input("Email:      ")
    user_data["Username"] = input("Username:   ")
    password = getpass(prompt="Password:  ").encode('utf-8')
    salt = bcrypt.gensalt()
    pass_hash = bcrypt.hashpw(password, salt)
    user_data["Password"] = pass_hash
    client = connect()
    db = client.companydb
    collection = db.Authentication
    result = collection.insert_one(user_data)
    print("Done!")
except Exception as e:
    print("Exception:",e)

MongoDB

> db.Authentication.find().pretty()
{
    "_id" : ObjectId("5a1d9cf8e6023f20d3b11bf3"),
    "Name" : "My Full Name",
    "Password" : BinData(0,"JDJiJDEyJDR0RzFwRkNjaE1HdlExd0kuRXgyLk91U09yQWZYTWxZL2pZbUVod3N2NGhRR05XUXIyNDRh"),
    "Username" : "ivanleoncz",
    "Email" : "mymail@post.com",
    "Sector" : "IT"
}

我想了解:

Why the hashed password is being stored as BSON BinData?

这是因为bcrypt.hashpw()returnsbytes数据类型。例如:

b'b$bvjnkItDoYvw.GUwBeVuwOuIxIQ5hUIx.ECovNrnYc1kgSP/kruXu'

同样在 PyMongo 中 (Python 3) 字节将被编码为 bson.binary.Binary(),反之亦然。

Can I avoid this situation? If it is possible, how?

如果您打算将散列存储在 MongoDB 中的字符串中,您可以在存储到字典中时对散列进行解码。即

user_data["Password"] = pass_hash.decode("utf-8")

# When checking later you would have to encode it back to bytes.
bcrypt.checkpw(b"mysecretpassword", user_data["Password"].encode("utf-8"))

如评论中所述,关于仅存储密码并恢复密码以便稍后进行身份验证,您可以将其保留为二进制文件(除非您的用例需要它)

这是因为当从 MongoDB 检索回文档时,在 Python 中 bson.Binary 的 3 个实例将直接解码回字节。您可以通过使用 find()

检索文档来对此进行测试

Is there any difference between: storing a dict directly vs insert_one

从回答中可以看出,这是bcrypt.hashpw()insert_one()的组合行为。