加密 mongodb 中的密码字段
Encrypt password fields in mongodb
我有以下代码,它将 userName
和 password
插入数据库
但密码以纯文本格式存储。我的意思是,当我查看数据库时,我可以看到插入的密码。
我想以encrypted
格式存储password
MongoClient client = new MongoClient("localhost",27017);
DB db = client.getDB("Test");
DBCollection collection = db.getCollection("EncryptionDemo");
BasicDBObject documentDetail = new BasicDBObject();
documentDetail.put("userName", "admin12");
documentDetail.put("password", "12345");
collection.insert(documentDetail);
我怎样才能做到这一点?
根据评论中的对话,您的意思是散列密码,而不是加密密码。你通常会用盐来防止彩虹 table 攻击。在数据库中存储密码时,将密码存储为加盐哈希值是最佳实践标准。
从 3.2 版开始,MongoDB 不像某些 SQL 数据库提供的那样对密码散列提供本机支持,因此您必须在 Java.[=27= 中实现它]
要生成新帐户或更改现有帐户的密码:
- 使用
java.security.SecureRandom
. This class works just like the standard random number generator java.util.Random
(它是一个子class)生成一个加密安全的随机盐值,但以性能换取更高级别的不可预测性,这是安全相关上下文所必需的。
- 通过连接盐和密码创建一个字符串
- 使用加密安全散列函数生成该字符串的散列。 Java 提供了许多开箱即用的散列函数,但您想使用一个故意难以计算的散列函数来减慢具有数据库访问权限的攻击者试图在他们的本地强制执行您的散列超级计算机集群。
javax.crypto.SecretKeyFactory
class. 支持的 "PBKDF2WithHmacSHA1" 算法是一个不错的选择
- 使用字段
username
、password_hash
和 password_salt
将文档保存到 MongoDB(当然还要加上您的实际申请数据)。不保存原密码。
要检索帐户:
- 阅读
username_input
和 password_input
涉嫌用户输入您的登录表单。
- 检索
username
与用户提供的 username_input
匹配的文档。
- 从该文档中获取
password_salt
字段
- 像以前一样通过连接
password_salt
和 password_input
创建一个字符串。
- 使用相同的加密安全散列函数生成该字符串的散列。
- 将散列值与文档的
password_hash
字段进行比较。当匹配时,用户输入了正确的密码。
您也可以只检索文档的 password_hash 和 password_salt 字段,而不在用户通过身份验证之前加载其余部分,但我认为在现实世界中它会导致更多负载比它会节省。成功登录的次数通常会大大超过不成功的登录次数,除非你有一个试图暴力破解帐户的攻击者。在这种情况下,您将使用 fail2ban 或其他登录限制机制阻止攻击者。
我想这个问题很老了,但现在似乎支持 fields-level encryption。此方法的工作原理与 mysql 中的密码字段哈希有很大不同。此外,部分 mongodb field-level 加密功能并非免费提供。
我有以下代码,它将 userName
和 password
插入数据库
但密码以纯文本格式存储。我的意思是,当我查看数据库时,我可以看到插入的密码。
我想以encrypted
格式存储password
MongoClient client = new MongoClient("localhost",27017);
DB db = client.getDB("Test");
DBCollection collection = db.getCollection("EncryptionDemo");
BasicDBObject documentDetail = new BasicDBObject();
documentDetail.put("userName", "admin12");
documentDetail.put("password", "12345");
collection.insert(documentDetail);
我怎样才能做到这一点?
根据评论中的对话,您的意思是散列密码,而不是加密密码。你通常会用盐来防止彩虹 table 攻击。在数据库中存储密码时,将密码存储为加盐哈希值是最佳实践标准。
从 3.2 版开始,MongoDB 不像某些 SQL 数据库提供的那样对密码散列提供本机支持,因此您必须在 Java.[=27= 中实现它]
要生成新帐户或更改现有帐户的密码:
- 使用
java.security.SecureRandom
. This class works just like the standard random number generatorjava.util.Random
(它是一个子class)生成一个加密安全的随机盐值,但以性能换取更高级别的不可预测性,这是安全相关上下文所必需的。 - 通过连接盐和密码创建一个字符串
- 使用加密安全散列函数生成该字符串的散列。 Java 提供了许多开箱即用的散列函数,但您想使用一个故意难以计算的散列函数来减慢具有数据库访问权限的攻击者试图在他们的本地强制执行您的散列超级计算机集群。
javax.crypto.SecretKeyFactory
class. 支持的 "PBKDF2WithHmacSHA1" 算法是一个不错的选择
- 使用字段
username
、password_hash
和password_salt
将文档保存到 MongoDB(当然还要加上您的实际申请数据)。不保存原密码。
要检索帐户:
- 阅读
username_input
和password_input
涉嫌用户输入您的登录表单。 - 检索
username
与用户提供的username_input
匹配的文档。 - 从该文档中获取
password_salt
字段 - 像以前一样通过连接
password_salt
和password_input
创建一个字符串。 - 使用相同的加密安全散列函数生成该字符串的散列。
- 将散列值与文档的
password_hash
字段进行比较。当匹配时,用户输入了正确的密码。
您也可以只检索文档的 password_hash 和 password_salt 字段,而不在用户通过身份验证之前加载其余部分,但我认为在现实世界中它会导致更多负载比它会节省。成功登录的次数通常会大大超过不成功的登录次数,除非你有一个试图暴力破解帐户的攻击者。在这种情况下,您将使用 fail2ban 或其他登录限制机制阻止攻击者。
我想这个问题很老了,但现在似乎支持 fields-level encryption。此方法的工作原理与 mysql 中的密码字段哈希有很大不同。此外,部分 mongodb field-level 加密功能并非免费提供。