这个问题的目的是防止一些不良分子查看源代码,直接访问MySQL并做一些... 好吧,不良的事情。
你不能。
如果密码存储在交付给最终用户的构件中,你必须认为它已经被泄露!即使构件是一个编译后的二进制文件,也总有(更或少复杂的)方法可以获取到密码。
保护你的资源的唯一方法是向最终用户公开有限的 API。要么建立一个编程接口(REST、WS+SOAP、RMI、JavaEE+Servlets 等等),要么只通过 SPROCs(见下文)公开数据库中的某些功能。
这里的问题不应该是如何隐藏密码,而应该是如何保护数据库的安全。请记住,仅使用密码通常是非常薄弱的保护措施,不应该将其视为保护数据库的唯一机制。你使用 SSL 吗?没有吗?那么,即使你设法在应用程序代码中隐藏密码,也很容易在网络上嗅探到它!
你有多种选择。每种选择都有不同程度的安全性:
为应用程序创建一个数据库用户。对该角色进行授权。一个非常常见的设置是仅允许 CRUD 操作。
DROP
查询(例如 SQL 注入)UPDATE
和 DELETE
查询(即:一次删除或更新整个表)。每个应用/最终用户创建一个数据库用户。这样可以定义原子访问权限,甚至可以基于列级别进行定义。例如:用户X只能从表foo选择列far和baz。什么都不能做。但是,用户Y可以“SELECT”所有内容,但不能更新,而用户Z具有完全的CRUD(select、insert、update、delete)访问权限。
一些数据库允许您重用操作系统级别的凭据。这使得对用户的身份验证透明化(只需要在工作站上登录,该身份就会被转发到数据库)。在完整的MS堆栈(OS = Windows,Auth = ActiveDirectory,DB = MSSQL)中,这很容易实现,但就我所知,也可能适用于其他数据库。
在应用程序中不要编写SQL查询。通过SPROCs运行 everything 。然后为每个用户创建数据库帐户,并仅将特权分配给SPROCs。
永远不要允许应用程序执行数据库管理任务。大多数情况下,应用程序只需要执行SELECT
、INSERT
、DELETE
和UPDATE
操作。如果您遵循这个指南,则用户发现密码的风险几乎不存在,除了上述提到的几点。
无论如何都要备份数据。我假设您希望保护数据库免受意外删除或更新的影响。但是事故难免发生,要时刻牢记这点;)
[files]
host=127.0.0.1
port=3307
database=files
default-character-set=utf8
password=foobar
并在数据库初始化时使用它
d=MySQLdb.connect(
read_default_group='files',
port=0, # read from .my.cnf
db='files',
cursorclass=cursors.DictCursor,
# amongst other stuff
)
my.cnf
文件必须位于客户端上。换句话说,它必须在运行应用程序的机器上。此外,应用程序通常在与用户相同的凭据下运行。这意味着用户需要读取文件的访问权限。因此,这将使其不太明显,但是熟练的攻击者仍然可以轻松定位到它。 - exhuma类似的未解决问题在这里:https://stackoverflow.com/questions/2850710/connect-to-a-db-with-an-encrypted-password-with-django Python DBAPI(PEP 249)没有接口可以使用加密/哈希密码连接到数据库,而不是明文密码。
虽然其他语言中的此功能很令人放心,但实际上并没有提供任何额外的安全性:密码的哈希值与密码一样好。您仍然必须像exhuma 描述的那样控制对数据库资源的访问。
无论是绑定 Python 还是不绑定,MySQL 本身都不提供任何额外选项。您可以在 MySQL 用户手册的 密码安全 部分中阅读他们的指导。保护密码访问的推荐选项是将其存储在选项文件中并保护该文件,如 glglgl 所述。
从那页上:
您可以在此处列出运行客户端程序时指定密码的方法以及每种方法的风险评估。简而言之,最安全的方法是让客户端程序提示输入密码或在受到适当保护的选项文件中指定密码。
要么使用像 root
这样简单的密码。否则不要使用密码。