代码之家  ›  专栏  ›  技术社区  ›  Funka

如何保证多个connectionString密码安全、独立且易于部署?

  •  3
  • Funka  · 技术社区  · 14 年前

    我知道这里已经有很多关于这个话题的问题(我已经读了尽可能多的内容),但是我还没有弄清楚如何最好地满足我的特定标准。目标如下:

    1. ASP.NET应用程序将在几个不同的Web服务器上运行,包括用于开发的本地主机工作站。 这意味着使用计算机密钥加密web.config的操作已退出。 Web服务器的每个“类型”或环境(dev、test、prod)都有自己的对应数据库(dev、test、prod)。我们希望分离这些连接字符串,以便开发人员处理“dev”代码时看不到任何“prod”连接字符串密码,也不允许将这些生产密码部署到错误的服务器或提交给SVN。

    2. 应用 应该能够根据服务器名称(使用switch语句)决定要尝试使用的连接字符串。例如,“localhost”和“dev.example.com” 应该知道使用devdatabaseconnectionstring,“test.example.com”将使用testdatabaseconnectionstring,而“www.example.com”将使用proddatabaseconnectionstring。这样做的原因是限制发生任何部署事故的可能性,即错误类型的Web服务器连接到错误的数据库。

    3. 理想情况下,完全相同的可执行文件和web.config应该能够在这些环境中的任何一个上运行,而不需要在每次部署时分别定制或配置每个环境(在部署过程中,似乎很容易忘记/弄乱一天,这就是为什么我们不再只使用一个connectionstri必须在每个目标上更改的ng)。当前通过ftp完成部署。 更新: 使用“构建事件”并修改部署过程可能不是一个坏主意。

    4. 我们将无法对生产Web服务器进行命令行访问。这意味着使用aspnet_regiis.exe加密web.config已退出。 更新: 我们可以通过程序实现这一点,所以这一点是没有意义的。

    5. 我们不希望在密码更改时重新编译应用程序,因此使用web.config(或db.config或其他任何方法)似乎最有意义。

    6. 开发人员不应该能够获取生产数据库密码。如果开发人员将源代码签出到他们的本地主机笔记本电脑上(这将决定它应该使用devdatabaseconnectionstring,还记得吗?)而且笔记本电脑会丢失或被盗,不可能找到其他连接字符串。因此,不能考虑使用一个RSA私钥取消对所有三个密码的加密。(与上面的3相反,如果我们走这条路线,似乎确实需要三个单独的密钥文件;这些文件可能每台机器安装一次,如果错误的密钥文件部署到错误的服务器上,最糟糕的情况是应用程序无法解密任何东西,并且不允许错误的主机访问错误的数据库!)

    7. 更新/附录:该应用程序有几个独立的面向Web的组件:一个经典的ASMX Web服务项目、一个ASPX Web表单应用程序和一个更新的MVC应用程序。为了避免在每个单独的项目中为每个单独的环境配置相同的连接字符串而发疯,最好只在一个地方显示这个字符串。(可能在DAL类库或单个链接配置文件中。)

    我知道这可能是一个主观的问题(要求一种“最佳”的方式去做一些事情),但是考虑到我提到的标准,我希望一个最佳答案确实会出现。

    谢谢您!

    3 回复  |  直到 14 年前
        1
  •  3
  •   MatthewMartin muthu    14 年前

    集成身份验证/Windows身份验证是一个不错的选择。没有密码,至少没有需要存储在web.config中的密码。事实上,这是我喜欢的选择,除非管理员明确地把它从我身上拿走。

    就个人而言,对于任何因机器而异的内容(不仅仅是连接字符串),我使用以下技术从web.config中输入外部引用: http://www.devx.com/vb2themax/Tip/18880

    当我向生产服务器管理员抛出代码时,他得到了一个新的web.config,但没有得到外部文件——他使用的是他以前的那个文件。

        2
  •  1
  •   Sonic Soul    14 年前
    1. 您可以拥有多个具有相同加密密钥的Web服务器。您可以在machine config中这样做,只需确保每个键都是相同的。

    一个常见的做法是将第一个加密的连接字符串存储在机器上的某个地方,如注册表。在服务器使用该字符串连接之后,它将检索数据库中管理(也加密)的所有其他连接字符串。这样,可以根据授权要求(请求者、正在使用的应用程序等)动态生成连接字符串,例如,可以根据上下文和用户/组使用不同的权限访问相同的表。

    我相信这个场景解决了所有(或大多数?)你的观点……

        3
  •  1
  •   Community Egal    7 年前

    (首先,哇,我想2到3个“快速段落”比我想象的要长一点!我走了……

    我得出的结论是(也许你会不同意我的看法),在服务器上“保护”web.config的能力(或者通过使用aspnet-iisreg)只有有限的好处,而且可能不是一件好事,因为它可能会给人一种错误的安全感。我的理论是,如果有人能够获得对文件系统的访问权,以便首先读取web.config,那么他们也可能有权创建自己的简单aspx文件,该文件可以“取消保护”,并向他们揭示其秘密。但是,如果未经授权的人在您的文件系统中四处游荡……那么您手头上有更大的问题,所以现在我的整个问题都没有了!

    我还认识到,也没有一种简单的方法可以将密码安全地隐藏在一个dll中,因为它们最终可以被反汇编和发现,也许可以使用类似ildasm的方法。 安全 模糊和加密二进制文件可以获得模糊性,例如使用dotfuscator,但这并不被认为是安全的,而且,如果有人对二进制文件和文件系统有读访问权(也可能有写访问权),那么您再次遇到了更大的问题。

    为了解决我提到的不希望密码存在于开发人员的笔记本电脑或SVN中的问题:通过单独的不存在于SVN中的配置文件来解决这个问题是(现在!)显而易见的选择。web.config可以在源代码管理中快乐地生活,而只是秘密部分不能。然而---这就是为什么我要用如此长的时间来跟进我自己的问题---我仍然采取了一些额外的步骤来尝试使这个问题变得更安全,那么至少要更安全一点。 模糊的 .

    我们想要保密的连接字符串(那些不是开发密码的字符串)永远不会以明文形式存在于 任何 文件夹。现在,它们首先用一个秘密(对称)密钥加密——当然,使用新的可笑的加密机(tm)!只是为了这个目的而构建的实用程序——在它们被放入一个__db.config_文件的副本之前。然后只将db.config上载到其各自的服务器。密钥直接编译到dal_s dll中,然后它本身(理想情况下!)用dotfuscator之类的东西进一步模糊和加密。希望这至少能避免任何偶然的好奇心。

    我不会太担心生活在DLL或SVN或开发人员笔记本电脑上的对称“dbkey”。这是密码本身,我会把它挡在外面。为了开发和调试,我们仍然需要在项目中有一个__db.config_157;文件,但是除了开发文件外,它中的所有密码都是假的。实际的服务器有实际的拷贝,只有它们自己的秘密。db.config文件通常被还原(使用svn)为安全状态,并且从未与真正的秘密一起存储在我们的Subversion存储库中。

    尽管如此,我知道这不是一个完美的解决方案(是否存在?)一个仍然需要一个带有一些部署提醒的Post-It注释,但它似乎已经足够多的麻烦了,除了最聪明和最坚定的攻击者之外,这些麻烦可能会很好地将所有人拒之门外。我不得不向“足够好”的安全部门辞职,这并不完美,但让我在感觉良好后重新开始工作,让它成为“大学尝试”!


    1。 根据我6月15日在这里的评论 http://www.dotnetcurry.com/ShowArticle.aspx?ID=185 -如果我不在基地就告诉我!-还有一些更好的评论 Encrypting connection strings so other devs can't decrypt, but app still has access 在这里 Is encrypting web.config pointless? 这里 Encrypting web.config using Protected Configuration pointless?

    2。 关于不同主题但非常相关的概念的良好讨论和思考的食物: Securely store a password in program code? -真正让人印象深刻的是从所选答案中链接的pidgin常见问题解答:如果有人有你的程序,他们可以了解它的秘密。