您好,向所有数据库/网络专家提出另一个新手问题......
我读过很多关于使用哈希、盐、加密算法等保护存储在数据库中的密码的内容。 为了避免混淆,我说有两个不同的密码...“数据库用户名/密码”和“应用程序用户名/密码”,其中会有很多。
我认为这是正确的......但由于我的应用程序可能有很多用户,我不会创建一个 每个人的新数据库用户,而不是他们都可以使用相同的数据库用户名/密码来访问数据库本身。选项将非常有限。 应用程序帐户设置(用户名和密码)将在数据库的表中加密。
我想知道是否/如何使用密码来防止用户读取数据库中的任何条目。
最好用一个例子来解释:
假设我有一个有 20 个用户的系统。 我将为每个人分配一个(应用程序)用户名和密码。
每个人都会从 PC 应用程序远程生成一些数据,然后将其上传到数据库。 表中的每一行都会有一个对上传它的“用户”的引用/列(以便稍后检索)。
假设有人出现(试图破解系统),而不是使用自己的用户名,开始使用不同的用户名,甚至执行 其他sql命令读取其他表条目。
如何编写应用程序(哪个平台)以确保访问数据库的用户只能访问自己的数据。
我确信开发人员之前已经多次这样做过,但是如果有人可以为我指出一些示例代码或教程的正确方向 我们将不胜感激。
太棒了!!!
最佳答案
- 请勿使用任何哈希函数的单次传递来存储密码。
- 请务必使用 8-16 字节范围内的随机盐。
相反,您的应用程序有一个用户选择关键字/密码:
- 生成加密随机 8-16 字节盐
- 使用 PBKDF2、BCrypt 或 SCrypt 以及上述盐和处理器可以处理的尽可能大的迭代计数/工作因子来创建密码哈希
- 如果您具体使用 PBKDF2,请勿请求比 native 哈希大小更大的输出(SHA-1 = 20 字节、SHA-256 为 32 字节、SHA-384 为 48 字节、SHA-512 为 64 字节) ),或者你增加了攻击者相对于你(防御者)的比较优势。
然后在您的数据库中,您的应用程序存储该用户的特定信息:
- 清澈的盐
- BINARY(8) 或 BINARY(16) 列
- 迭代次数/工作因子
- INT UNSIGNED 列
- 这样您以后就可以轻松更改/升级它
- 生成的密码哈希值
- 可能是用于任何 20 字节输出长度 PBKDF2-HMAC-SHA-x 的 BINARY(20) 列,或者用于 192 位 BCrypt 的 BINARY(24) 列,或者用于 PBKDF2- 的 native 输出大小的 BINARY(64) 列HMAC-SHA-512
- 或者,您可以对 PBKDF2/BCrypt/SCrypt 的二进制输出进行 Base64 编码,但必须确保使用区分大小写的比较或在检索后对其进行 Base64 解码
- 身份验证协议(protocol)的版本 - 这可能是 1,也可能是 0。
- TINYINT UNSIGNED 列
- 因此,如果您稍后从此方法转移到 NewWellKnownMethod,您可以轻松更改/升级它
当用户想要向您的系统进行身份验证时,您:
- 从数据库中检索其版本、salt、迭代计数/工作因子以及生成的哈希值
- 使用数据库中的盐和迭代计数/工作因子对他们刚刚输入的任何关键字/密码进行哈希处理。
- 将刚刚得到的结果与数据库中的结果进行比较;如果他们相同,就让他们进来。
- 高级:使用恒定时间比较,因此如果第一个字节不同,它不会停止尝试,以减少定时攻击的漏洞。
对用户进行身份验证后,您需要在某些权限表中查找该用户并确定允许他们执行哪些操作,或者使用其应用程序级别用户名作为应用程序执行的每个查询的参数确保他们只检索自己的数据。
请阅读How to securely hash passwords? ,其中 Thomas Porrin 的答案是目前最常被提及的 Stackexchange 关于密码哈希的论文,当然也是我迄今为止见过的最好的答案。
关于mysql - 如何使用密码保护数据库数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23460774/