database 保持密码可配置的最佳方法是什么,又不会让普通读者太容易获得密码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/258299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to keep passwords configurable, without having them too easily available to the casual human reader?
提问by AshtonKJ
I have a database that many different client applications (a smattering of web services, some java apps and a few dot net applications) connect to. Not all of these are running on windows (Sadly, otherwise it would make this an easy answer question with just enabling windows authentication for database connections). At the moment, the passwords are stored in various configuration / properties files lying around the systems. Ideally, only the support staff have access to the servers where the files are running, but if someone else gains access to one of the servers, they would have enough database permissions to get a fair whack of data as it stands now.
我有一个数据库,许多不同的客户端应用程序(少量的 Web 服务、一些 Java 应用程序和一些 dot net 应用程序)连接到该数据库。并非所有这些都在 Windows 上运行(可悲的是,否则只需为数据库连接启用 Windows 身份验证,就会使这成为一个简单的答案问题)。目前,密码存储在系统周围的各种配置/属性文件中。理想情况下,只有支持人员才能访问运行文件的服务器,但如果其他人获得了其中一台服务器的访问权限,他们将拥有足够的数据库权限来获取当前数据的公平重击。
My question then, What is the best way to keep the passwords configurable, without having it too easily available to the casual human reader?
那么我的问题是,保持密码可配置的最佳方法是什么,又不会让普通读者太容易获得密码?
EditJust to clarify, DB server is Windows Server 2003, running MSSQL 2005.
编辑只是为了澄清,数据库服务器是 Windows Server 2003,运行 MSSQL 2005。
PS: I don't see any questions that this duplicates, but if there are, please feel free to close this one.
PS:我没有看到任何与此重复的问题,但如果有,请随时关闭此问题。
采纳答案by WW.
I'm assuming you want to hide the passwords from casual observers. If they were evil, steely eyed observers with access to all the source code on one of the machines that connects, then they can get the password with a bit of reverse engineering.
我假设您想对临时观察者隐藏密码。如果他们是邪恶的、目光坚定的观察者,可以访问其中一台连接的机器上的所有源代码,那么他们可以通过一些逆向工程获得密码。
Remember that you do not need to use the same protection for each different client. A few steps:-
请记住,您不需要为每个不同的客户端使用相同的保护。几个步骤:-
- Create different database accounts for different systems that access your database
- Limit access on the database to only what they need using your inbuilt database GRANTs
- Store a triple DES (or whatever) key inside a password manager class on your database. Use this to decrypt an encrypted value in your properties file.
- 为访问您的数据库的不同系统创建不同的数据库帐户
- 使用您的内置数据库 GRANT 将数据库的访问权限限制在他们需要的范围内
- 在数据库的密码管理器类中存储三重 DES(或其他)密钥。使用它来解密属性文件中的加密值。
We have also considered having the application prompt for a pass-phrase on startup but have not implemented this as it seems like a pain and your operations staff then need to know the password. It's probably less secure.
我们还考虑过让应用程序在启动时提示输入密码,但尚未实现,因为这看起来很麻烦,您的操作人员需要知道密码。它可能不太安全。
回答by neesh
Let's assume the following common scenario:
让我们假设以下常见场景:
You use the same code base for all environments and your code base has the database passwords for each environment.
The personnel (sysadmins, configuration managers) that have access to your production application server are allowed to know the production database passwords and no one else.
You don't want anyone with access to the source code to know what the production passwords are.
您对所有环境使用相同的代码库,并且您的代码库具有每个环境的数据库密码。
有权访问您的生产应用程序服务器的人员(系统管理员、配置经理)可以知道生产数据库密码,而其他人则不得。
您不希望任何有权访问源代码的人知道生产密码是什么。
In a scenario like this, you can encrypt and store the production passwords in property files that your application. Within the application you can include a class that reads the passwords from the property file and decrypts it before passing it to the database driver. However, the key and the algorithm used to decrypt the password are not part of the source code but rather passed to the application as a system property at runtime. This decouples the knowledge of the key from the application source code and anyone with access to just the application source code will no longer be able to decrypt the password because they do not have access to the application's runtime environment (app server).
在这种情况下,您可以加密生产密码并将其存储在您的应用程序的属性文件中。在应用程序中,您可以包含一个类,该类从属性文件中读取密码并在将其传递给数据库驱动程序之前对其进行解密。但是,用于解密密码的密钥和算法不是源代码的一部分,而是在运行时作为系统属性传递给应用程序。这将密钥知识与应用程序源代码分离开来,任何只能访问应用程序源代码的人将无法再解密密码,因为他们无权访问应用程序的运行时环境(应用程序服务器)。
If you are using Java take a look at thisfor a more concrete example. The example uses Spring and Jasypt. I am confident that some thing like this can be extrapolated to other environments like .Net
如果您使用的是 Java,请查看此内容以获得更具体的示例。该示例使用 Spring 和 Jasypt。我相信这样的事情可以外推到其他环境,如 .Net
回答by neesh
At my old workplace we used to have a system whereby all passwords were encrypted (using Triple DES or whatever we were using at the time). The passwords were often stored in properties files (this was in a Java system).
在我以前的工作场所,我们曾经有一个系统,所有密码都被加密(使用三重 DES 或我们当时使用的任何东西)。密码通常存储在属性文件中(这是在 Java 系统中)。
When the password needed to be changed, we could simply use "!plaintext" as the value, and then our code would load it up, encrypt it, and store the encrypted value back in the properties file.
当需要更改密码时,我们可以简单地使用“!plaintext”作为值,然后我们的代码将加载它,对其进行加密,并将加密后的值存储回属性文件中。
This meant that it was possible to change the password without knowing what the original value was - not sure if that's the kind of thing you were asking for!
这意味着可以在不知道原始值的情况下更改密码 - 不确定这是否是您要求的类型!
回答by Timothy Khouri
It sounds like there is no easy answer (because of the different types of applications that connect)... really, the only issue I see is the Java Apps which seem to connect directly to your database. Is that correct?
听起来没有简单的答案(因为连接的应用程序类型不同)...实际上,我看到的唯一问题是 Java 应用程序似乎直接连接到您的数据库。那是对的吗?
If so, here's what you can do:
如果是这样,您可以执行以下操作:
1) Change any client-side applications that connect directly to the DB to go through a service. (If they haveto connect directly, then at least give them a first step to "get password" from a service, then they can connect directly).
1) 更改直接连接到数据库的任何客户端应用程序以通过服务。(如果他们必须直接连接,那么至少给他们第一步从服务“获取密码”,然后他们可以直接连接)。
2) Store the passwords in the web.config file (if you chose to do .Net web services), and then encrypt the "connection strings" section of the file.
2) 将密码存储在 web.config 文件中(如果您选择做 .Net Web 服务),然后加密文件的“连接字符串”部分。
回答by paan
Don't use passwords, server to server authentication can usually be performed by using a key file or a client cert or some other way other than a password.
不要使用密码,服务器到服务器的身份验证通常可以通过使用密钥文件或客户端证书或密码以外的其他方式来执行。
回答by Bork Blatt
You could use a reversible encryption algorithm e.g. Blowfish to store the passwords as a stopgap measure. There should be a number of free libraries you can use to build this into all your programs that need this access.
您可以使用可逆加密算法(例如 Blowfish)来存储密码作为权宜之计。应该有许多免费库可以用来将它构建到需要此访问权限的所有程序中。
Bruce Schneier's page on Blowfish
布鲁斯·施奈尔 (Bruce Schneier) 关于河豚的页面
Wikipedia article on Blowfish
维基百科关于河豚的文章
回答by tunaranch
For the java stuff, if you're using an app server see if you can define a data source, and your apps can get at the data source using JNDI. That way, managing the datasource (including connection details) is handled by the app server, and your application code has to do is ask for a datasource.
对于 java 的东西,如果您使用的是应用程序服务器,请查看是否可以定义数据源,并且您的应用程序可以使用 JNDI 获取数据源。这样,管理数据源(包括连接详细信息)由应用程序服务器处理,您的应用程序代码要做的就是请求数据源。
回答by Ken Gentle
NTLM Authentication or LDAP-based (Active Directory) authentication should be available to you with a bit of effort. This would allow you to use your "windows authentication" across applications.
NTLM 身份验证或基于 LDAP(Active Directory)的身份验证应该可以通过一些努力为您提供。这将允许您跨应用程序使用“Windows 身份验证”。
It may mean a bit of a migration for your operations staff, but SSO for a set of applications is nice.
对于您的操作人员来说,这可能意味着一些迁移,但是一组应用程序的 SSO 很好。
回答by meme
Yes I have to agree with the option of storing the (salted) hashes. I would recommend a (salted) SHA256 hash of the password stored in the database. Also don't forget to enforce secure password rules.
是的,我必须同意存储(盐渍)散列的选项。我会推荐存储在数据库中的密码的(加盐)SHA256 哈希值。另外不要忘记强制执行安全密码规则。
回答by axiopisty
My interpretation of your question is that you are asking specifically how to store configuration passwords that your code will use to connect to services it depends on such as a database or third party API. In that case, you may want to consider using a service which provides a secrets container such as Hashicorp's Vault.
我对您的问题的解释是,您特别询问如何存储您的代码将用于连接到它所依赖的服务(例如数据库或第三方 API)的配置密码。在这种情况下,您可能需要考虑使用提供机密容器的服务,例如Hashicorp 的 Vault。
You can think of vault as a web service your application can connect to in order to lookup the secrets your application needs at application runtime.
您可以将保险库视为您的应用程序可以连接到的 Web 服务,以便在应用程序运行时查找您的应用程序所需的机密。
As an example, lets assume your application needs to connect to a database but you don't want to store your database credentials with your application source code in your version control system. Furthermore, lets assume that you want the database credentials used by your application to be different each time your application starts. In this case, you could enable and configure the database secret back end in vault. This means that vault will dynamically create your database credentials as a service, and then provide your application with a revocable leased token for some duration of time. Vault, of course, will allow you to store any secret in it.
例如,假设您的应用程序需要连接到数据库,但您不想将数据库凭据与应用程序源代码一起存储在版本控制系统中。此外,假设您希望应用程序使用的数据库凭据在每次应用程序启动时都不同。在这种情况下,您可以在 Vault 中启用和配置数据库机密后端。这意味着 Vault 将动态创建您的数据库凭据作为服务,然后在一段时间内为您的应用程序提供可撤销的租用令牌。当然,Vault 将允许您在其中存储任何秘密。
Vault provides secure ways for your application to connect to it. One such authentication method uses what is known in vault as the Cubbyhole Secrets Engine.
Vault 为您的应用程序提供安全的连接方式。一种这样的身份验证方法使用在保险库中称为Cubbyhole Secrets Engine 的东西。