转载

评论专栏: 加密 WebSphere Application Server 系统密码 = 如果您坚持这么做

简介

似乎每一天,我们都会看到计算机系统被攻击的技术案例和主流媒体报道,这些系统中的密码被盗后,流入到了攻击者手中。这种报道常常指出,这些密码数据能够被获取的一个原因是 “它们没有 加密 ”。在这种情况下,一定要认识到这里所说的密码并不是用户密码,不是用于登录和访问系统的密码,不是与系统进程和二进制程序关联的密码。这是一个非常重要的区别。因此,我想说如果 没有额外的背景 ,“未加密的密码不安全” 的前提在技术上不准确的,而且具有误导性。

考虑到这些新闻报道,或许 WebSphere 安全顾问从我们的技术销售人员和 WebSphere 安全开发架构师收到的最常见的评论,都与客户想要加密其 IBM WebSphere Application Server 系统中的密码相关。我们反复获得的消息是, “WebSphere 最符合它的 默认安全 主张,但密码经过简单编码后存储在文件系统上,没有加密。” 随后的结果常常是 “我们没有通过安全审核,因为它们没有加密。”

首先,从安全角度讲, IBM WebSphere 软件服务部 和 IBM WebSphere Development 的定位是 系统密码的编码不等于暴露 。发出这些声明的审核人员不理解他们声称的首选解决方案的安全影响。我稍后会为证明这一定位的合理性。

但是,因为一些客户坚持加密 WebSphere Application Server 所使用的系统密码更优于编码,所以从 6.0.2 版开始,WebSphere Application Server 中提供了一个系统编程接口 (SPI),该接口可用来实现客户可能想要实现的密码 “隐藏” 解决方案。通过这个 SPI,IBM WebSphere 软件服务部为许多客户实现了这样一个解决方案。我将首先定义一些基本的安全概念,然后介绍这个自定义解决方案中的设计考虑因素。

回页首

基础知识:编码与加密

编码与加密之间有何区别?我们使用术语 “编码” 来表示一种通过公式或算法隐藏信息的模式。考虑您想要 “隐藏” 的保密密码的一个例子。为了演示,假设我有一个公认的非常弱的密码: SecretMonkey 。可使用一种可逆的算法编码此短语来 “隐藏” 它的真实值。

尤利乌斯•凯撒的成功归因于他使用了一种称为旋转密码或 ROT 密码的编码模式,其中字母表中的字母位置会移动一定的位数。现在将这种密码称为凯撒密码。ROT3 密码将字符映射到其右侧第 3 个字符。ROT3 映射(对于英文字母表)为:

明文:ABCDEFGHIJKLMNOPQRSTUVWXYZ<br /> 密文:DEFGHIJKLMNOPQRSTUVWXYZABC

我的 ROT3 密文密码然后变成:

明文:SecretMonkey<br /> 密文:VhfuhwPrqnhb

看到这个编码的字符串时,专业密码破译者很快会猜出编码算法,并使用逆向算法 (ROT-3) 对它解码。编码的优势在于算法的隐蔽性。一定要记住,攻击者非常熟悉对算法进行逆向工程。一旦知道了算法,数据就会失去保护。

与编码相反,加密的安全性不是基于所使用的算法,而基于难以猜测的密钥的强度。仍会使用算法,但这些算法(通常)是大家都知道和理解的。加密算法与编码算法的不同之处在于,它们接受两个输入:文本和秘密密钥。采用同样的方式,4 位借记卡 PIN 使用了 10,000 (10 4 ) 个可能的秘密中的一个,加密密钥使用一个秘密密钥,暴力猜测这个密钥需要很大的工作量。

有两种类型的加密,二者都基于复杂的数学原理。第一种类型的加密涉及单个密钥,被称为共享密钥、秘密密钥或对称密钥加密。考虑两个函数:

cipherText = Encrypt(plainText, secretKey);

和它的逆向函数:

plainText = Decrypt(cipherText, secretKey);

为了保护我的数据,从一个非常大的密钥集选择了一个密钥(比如一个 256 位密钥,这是 2 256 个可能的数字,一个非常大的数量;用十进制表示为 1.15x10 77 :一个 115 后跟 75 个额外的数字)。可以想象,调用 Decrypt 函数来迭代所有可能的密钥会花很长时间。

第二种类型的加密使用两种不同或非对称的密钥。这种类型的加密称为公钥或非对称加密。这两个密钥通过一种复杂的数学关系而彼此关联。撇开数学原理不谈,加密文本的函数调用为:

cipherText = Encrypt(plainText, KeyA);

它的非对称逆向函数为:

plainText = Decrypt(cipherText, KeyB);

这里的重点在于,两种类型的加密的优势都依赖于猜测解密函数需要的密钥参数的困难性 - 无论是使用对称加密来加密数据的共享 “secretKey”,还是用于非对称加密的 “KeyB”。

回页首

计算密码的哈希值

我在这里希望再提供点理论,介绍以下一种所谓的称为单向哈希函数的概念。我同样不会介绍数学原理,因为细节实际上对我的观点并不重要。单向哈希函数(同样)使用一个大家都知道和理解的算法:

digest = hash(inputString);

其中 inputString 转换为称为摘要的输出,对该过程求逆在计算上是不可行的(因此使用 “单向” 这个词)。每一次提供相同的 inputString 时,您都会获得完全相同的摘要。对于一个特定的哈希函数,摘要的长度通常不变。哈希函数的一个额外特性是,如果您更改输入中的任何一位,将获得完全不同的摘要输出。

普通的哈希函数可生成 8 位摘要。每个输入 “字符串” 将生成 2 8 个摘要中的一个。如果输入中的一位更改,将生成一个不同的摘要。如果您仍在观察,您会认识到有无限多个输入字符串会生成相同的摘要。但我们知道,给定一个摘要,不可能猜出 inputString。摘要大小足够大时(例如 2 256 位),另一个随机输入生成相同的摘要的概率将无限小。

攻击者已认识到,对于一种已知的算法,可以预先生成所有可能的输入,然后计算它们自己的摘要。这些摘要称为 “彩虹” 表。在实际中,实施者通过将任何字符串与一个称为 “盐” 的秘密/不同前缀串联,以更改哈希函数的行为。所以首选的用法是:

digest = hash(inputString||salt);

攻击者需要构建包含所有可能的 salt 字符串的彩虹表。

您可能会问,为什么我在闲聊,而没有说到重点?这些密码被盗的数据库的新闻报道谈论的系统中, 用户的 密码未针对数据库而检查,而且悲痛的是数据库中的数据没有受到正确保护。在 IT 领域,大家都认为这些密码不应以明文形式存储,它们应包含具有盐的密码的摘要。换句话说,密码 “repository” 不应包含我的密码字符串 “SecretMonkey”。验证我的密码时,系统应串联它为为我的字符串使用的特定的盐,计算这个串联字符串的哈希值,然后将它与保存的密码摘要进行比较。如果这两个摘要匹配,则 inputString – “SecretMonkey” – 是我的密码的概率极高。

一个对我的包含不同盐的字符串计算哈希值的虚构例子可能是:

  • SecretMonkey(没有盐)> !GHD&@DB&!DJD
  • SecretMonkey||(盐=1111)> UCHAKJ$HDJS
  • SecretMonkey||(盐=2222)> njurnasiurrjfdd

至关重要的是,您的安全审计要确保这些密码以哈希值形式存储。请注意,我没有说加密。我希望您理解这里面的细微区别(一个是可逆的,另一个不是)。

但我还没完成。毫无疑问,我支持任何表明 最终用户密码必须存储为已加盐、哈希化的 摘要的人。但最终用户密码与系统密码之间存在巨大的差别。

回页首

用户密码不是系统密码

当 WebSphere 系统审计 “失败” 时,原因是系统密码步 “安全”,审计人员不会看到 “用户” 密码。这些是与 WebSphere Application Server 运行时使用的操作系统用户 ID 关联的密码,或者 WebSphere Application Server 应用程序用于连接到其他系统的密码。例如,当我登录到 “Financial” 应用程序时,我可以想象会发生以下情况:

  • 我已针对 LDAP 进行了验证。一次 LDAP 绑定操作使用了我的用户 ID 和密码。这个 LDAP 服务器计算该密码(和它的惟一的盐)的哈希值,并将得到的摘要与我保存的摘要进行比较,以确认或拒绝我的身份声明。
  • 经过验证后,这个 Web 应用程序连接到一些后端数据库来查找新的 “通知” 和 “网络请求”。这可能是一个类似 “select notifications where userid=Lansche” 的 SQL 命令。为了预防网络中的任何计算机访问此数据,“Financial” 应用程序使用 “FinancialApp” 凭据连接到该数据库。为便于讨论,我们假设这些凭据是一个用户 ID 和密码。

应用服务器需要密码来执行 LDAP 搜索,连接数据库、队列管理器、Web 服务和其他应用程序,以及获取应用程序的 runAs 身份。当应用服务器使用一个用户 ID 和密码向其他这些系统执行验证时,该密码需要以一种 “可用的” 格式发送 - 密码的明文版本。正如我的同事 T. Rob Wyatt 在他的 博客 中解释的:

发件人:存储和转发:加密配置文件中的密码 – 安全与否?

最终结论都可归结为:任何必须无人值守地引导仅操作状态的系统,都必须能够访问一个实用的身份验证凭据……“无人值守” 表示系统必须在没有人干预的情况下启动进入正常操作状态。在重新启动服务器后,所有应用程序都启动一个命令提示符来等待用户输入所有密码,是否能接受这一点?通常无法接受。完全无法接受。在某些情况下,这是可以接受的,但我没有对这些系统进行安全调查,如果我进行了调查,我就不会再写这篇文章了。对于其他所有人,我们都需要能在无人干预下自动恢复的系统。基本来讲,“无人值守” 意味着凭据必须存储在应用程序可在运行时访问的地方,通常是在文件系统中。

换句话说,当 “Financial” 应用程序启动时,您有两个选择:

  1. 等待操作员在控制台键入用户 ID “FinancialApp” 的密码(以及需要的其他每个系统帐户),或者
  2. 应用程序从文件系统上的某处获取密码。

我相信真实的应用程序会采用第二种模式。大多数非军事/国家安全系统都采用第二种模式。

回页首

PCI-DSS 和系统密码

所以,您的审计人员会说这些系统密码必须加密。 PCI-DSS 不包含这个具体需求。事实上,谈到系统密码,他们谈到的惟一一点要求是, “不使用供应商提供的默认值作为系统密码和其他安全参数。”

图 1 来自 PCI DSS - 需求和安全评估过程第 2.0 版的表

评论专栏: 加密 WebSphere Application Server 系统密码 = 如果您坚持这么做

规范中当然还有其他地方提到 “密码”,但这些明显与用户密码相关。例如,需求 8 规定,您 “向每个能访问计算机的人分配一个惟一 ID”,作为该需求的一部分,8.4 节要求密码 “在传输和使用强加密算法存储在所有系统组件上时必须无法读取”。这至关重要 - 用户密码不应以未哈希化的格式存储在任何地方;正如我之前提到的,惟一存储的信息应是加盐的单向哈希值!但是,这显然指的是用户密码,而不是系统密码。

回页首

为什么加密的密码不比编码的密码更安全

不过,假设您的审计人员坚持这么要求。让我们分析一下系统现在经历的逻辑过程。

  1. 假设编码密码不够安全。为什么?因为任何拥有文件系统板的读访问权的人都能够访问这些凭据:
    • 或许用户能够访问文件系统,或者
    • 在 WebSphere Application Server 中运行的应用程序能够读取密码,或者
    • 在 WebSphere Application Server 外运行的应用程序(或许是操作系统中的应用程序,它们由于某个未预见的漏洞)允许远程查看或窃取文件系统中的文件。
  2. 您实现密码编码 SPI,并加密密码。为此,您需要一个密钥。该密码现在以加密形式存储在文件系统上。假设采用对称加密(它比非对称加密更快)。您将密钥存储在一个密钥库中。
  3. 要能够从加密的文本转换回明文,服务器需要解密密钥。服务器从密钥库读取该密钥。要预防任何应用程序能够容易地从密钥库获取该密钥,您对密钥库进行密码保护。WebSphere Application Server 需要访问该密码才能读取密钥库。该密码保存在何处?因为提示操作员是不可接受的,所以该密码存储在文件系统上的一个文件中(请鼓掌吧);包含使应用程序能够读取密钥库的密码的文件称为 “贮藏 (stash)” 文件。

但是等等!我们在第 1 步中已说过,我们的根本问题是,我们无法控制哪些进程能够访问文件系统。 我们仍存在此问题。 现在稍微麻烦一点,但获取此系统密码所需的所有信息仍保留在文件系统上,可供 WebSphere Application Server 或在该应用服务器内运行的应用程序访问:

  1. 以密文形式存储在 WebSphere Application Server 配置文件中的密码。
  2. 包含解密密文所需的密钥的密钥库。
  3. 包含从密钥库读取密钥所需的密码的贮藏文件。

我们只是将问题转移到了别处。这并不比在文件中对密码进行编码更安全。事实上,T-Rob 在他的 博客文章 中提出了一个有吸引力的观点:加密系统密码会降低系统的安全性。

要解决的真正的安全问题是,控制谁(人或应用程序)能够访问文件系统。解决这个真正的安全问题的最佳方式已在我的安全性加强文章 中讨论过。(提示:使用文件系统访问控制。)

回页首

在何处加密系统密码能有所帮助

本文最初发表时,密码编码与加密的讨论到此就结束了。您不应推断密码加密不好。相反,应指出除了基础设施加强,还必须考虑人员、WebSphere Application Server 外的其他应用程序和在 WebSphere Application Server 中部署和运行的 Java EE 应用程序中的弱点。

将其配置 XML 文件提交到 Stackoverflow 的管理员会意外地泄露他已编码的密码。将这些 XML 文件发送给 IBM 来用于支持目的,也会泄露这些文件。但是,在两种情况下,加密的密码都可避免意外发布或共享系统密码。

您系统上的任何其他应用程序都可能包含安全错误,这使得读取和窃取文件成为可能 - 如果该应用程序可以 WebSphere 用户(或根用户)的身份运行,并且这些文件可从系统窃取,那么对 WebSphere Application Server 文件进行密码加密只会使解密这些密码稍微困难一点。

应用程序的弱点可能是粗心的设计或编码导致的,或者可能是恶意的程序员导致的。依赖于程序员有多粗心,密码的加密可能使攻击者的工作稍微困难一点或困难得多。请记住,如果有恶意编码人员蓄意尝试获取密码,那么密码加密也无法阻止他们。请反复阅读以上各节;密码加密不会阻止恶意的编码者 - 他将利用容器使用的相同代码来解密密码。

让我们返回到粗心的程序员问题上。考虑一个虚构的应用程序,它使用户能够向其浏览器呈现日志文件的内容。程序员没有向用户呈现文件列表,他提供了一个输入字段来让用户输入文件名。这个粗心实现的应用程序未验证输入来阻止指定绝对或相对路径。这种验证的缺乏导致了一个路径遍历漏洞。攻击者尝试执行路径遍历攻击,以检查他是否能看到文件系统上的随机文件的内容。如果攻击者可指定文件系统上一个包含未加密密码的文件的路径,就会显示此文件,我想我们都会觉得这个结果很糟。

无论使攻击者能够窃取文件的攻击矢量是什么(是一个出于好意但粗心实现的应用程序函数,还是系统中其他某个应用程序中的漏洞),加密密码都会使获取明文密码变得更困难,但收效甚微。此刻,您应该返回阅读上面有关解密机制的章节。

如果该攻击者也可窃取文件系统上包含加密密钥的密钥文件(WebSphere Application Server 必须能够读取它),那么攻击者现在拥有确定名为密码所需的两部分信息。攻击者需要知道该文件的名称 - 但配置文件中必须有某个属性指定了密钥文件的名称。获取 3 个文件比获取一个文件更难,但不会难很多。通过一个浏览文件功能来呈现二进制密钥文件可能使确定密钥变得更难,但不是不可能。

除了内部开发的应用程序,购买的应用程序也需要采取行动来阻止路径遍历漏洞,或者其他向用户返回不受限制的文件内容的漏洞。如果存在这些漏洞,那么它们是高优先级的安全漏洞。在 IBM 产品中发现漏洞时,我们提供了补丁来阻止访问,但我们不会控制在您系统上运行的所有应用程序,无论是否在 WebSphere Application Server 中。

现在您可能会问 “如果我不将从其他地方获取的密钥文件存储在文件系统上,结果会怎样?”可以考虑两种替代方案:硬件密钥库(或密钥)通过某种程序化的 API 读取 - 服务调用、数据库查询、HTTP 请求等。如果攻击者仅能查看文件系统上的文件,但运行的 WebSphere Application Server 必须执行一些代码来获取密钥,那么加密可能有所帮助。但是请记住,恶意编码者可蓄意地编写代码来使用 WebSphere Application Server 所使用的 API 获取密码。

回页首

如果您(仍然)坚持……

定义您自己的密码处理函数的接口是 com.ibm.wsspi.security.crypto.CustomPasswordEncryption 接口。我们创建了一个 com.ibm.wsspi.security.crypto.CustomPasswordEncryptionImpl 类,将该类放在 <WAS>/lib/ext 目录中。WebSphere Application Server 进程将使用此类,而无需进一步的管理配置。只能有一个类实现该接口。此接口定义以下方法(跟预期的一样):

清单 1

EncryptedInfoencrypt(byte[] decrypted_bytes)                       throws PasswordEncryptException byte[] decrypt(EncryptedInfo info)                throws PasswordDecryptException void initialize(java.util.HashMap initialization_data)

最后一个方法保留供将来使用,目前未被 WebSphere Application Server 运行时调用。

WebSphere Application Server 通过两种方式与这些密码交互:它在密码更改时存储这些文件,以及读取这些文件来包含密码。

WebSphere Application Server 存储一个已更新的密码时,它会检查是否有一个自定义的加密提供程序。如果有一个提供程序,它将获得明文密码。该提供程序应以某种方式处理该密码,并向 WebSphere Application Server 返回对提供程序有意义的二进制信息。WebSphere Application Server 然后将此二进制信息存储在合适的 XML 文件中,跟平常一样。存储的数据表明它已使用一个自定义提供程序编码。这会影响未来的读取。

当 WebSphere Application Server 需要密码时,它会读取配置信息(存储为 XML 文件),检查该信息来确定是否使用了自定义提供程序。如果密码采用默认方式编码,WebSphere Application Server 会像平常一样在内部对它解码。如果使用了自定义提供程序,WebSphere Application Server 会将编码的二进制信息传递给用户定义的提供程序(如果有一个这样的提供程序),如果没有该提供程序,将发生错误。然后该提供程序负责向 WebSphere Application Server 返回使用该二进制数据表示的明文密码。

这个懒惰读/写模型意味着,在任何给定时刻,在一个 WebSphere Application Server 单元中,可能存在使用默认机制编码的密码,也可能存在其他使用自定义机制编码/加密的密码。而且,如果提供程序允许更新加密密钥(像我们的提供程序一样),则可能多个使用不同密钥加密的密码存储在同一个单元中。因此,提供程序必须能够解密使用任何以前的加密密钥来加密的密码。我们的提供程序解决此问题的方式是,保留多个密钥版本,并将密钥版本嵌入在加密的密码的相关信息中。

回页首

我们的提供程序的设计亮点

本文剩余部分介绍 IBM Software Services for WebSphere 自定义密码加密提供程序。这不是可免费获取的代码,本文也没有提供可下载的附件。这是 IBM WebSphere 软件服务部的一个服务资产,可通过付费服务活动从 IBM WebSphere 软件服务部获得。在此服务活动期间,IBM WebSphere 软件服务部顾问将与您联系,了解和记录您的需求,并在需要时调整资产来更好地满足您的使用情况。他们然后会给您留下您自己的资产代码副本,以便您在企业中使用。

让此代码可用作 IBM WebSphere 软件服务部资产的重要推动因素是,尽管使用此代码具有非常少的实际安全价值,但真正的价值在于使客户能够在出现这方面的问题时通过安全审核,尽管事实上系统密码的编码并不是一种安全风险。在我们的经验中,如果在服务活动期间允许 IBM WebSphere 软件服务部安全顾问与 PCI 审核人员互动,他或她很可能能够向审核人员告知系统密码与用户密码之间的区别,否定部署(进而拥有和负责管理)该代码的需求!

IBM WebSphere 软件服务部自定义密码加密提供商实现中的关键设计决策是,尽可能多地利用现有的 Java JCE 基础架构。因此,用于密码加密和解密的对称密钥使用 Java KeyStore 支持功能来存储。具体来讲,我们选择使用 JCEKS 格式,因为此格式能够正确支持对称密钥。Java KeyStore 允许使用密码对存储在密钥库中的密钥进行加密,还允许使用密码对密钥库文件进行加密。无需要求人们想出一个恰当的密码,我们会自动生成一个非常长(30 多个字符)的字母数字密码并存放在另一个文件中:我们的存放文件或主密码文件。为了预防频繁的窃听,该文件的内容经过了异或运算(使用一个四字符的异或标志),让猜测变得非常困难。

当 WebSphere Application Server 需要加密任何系统或 WebSphere Application Server 密码时,会调用提供程序。提供程序应返回一个字符串和加密的字节。(一定要注意的是,如果使用 Federated Repositories 用户注册表中基于文件的存储库,用户密码是单向的、加盐的哈希密码。WebSphere Application Server 不使用此 SPI 编写这些用户密码)。当 WebSphere Application Server 需要解密一个密码时,它检查使用的是自定义提供程序还是默认提供程序。如果使用自定义提供程序,那么应该为它提供一个字符串(由提供程序定义)和一些字节。提供程序的工作是以字符数组的形式返回密码。我们利用该字符串来存储有意义的信息。

要知道,WebSphere Application Server 不会自动加密所有密码。它只是开始将该代码用于新的加密,所以我们的代码添加了强制 WebSphere Application Server 重新加密所有密码的功能。

为了支持加密密钥的管理和定期更新,从而无需存储整个单元,我们需要同时支持多个密钥版本。为此,我们在提供给 WebSphere Application Server 的字符串中嵌入了用于加密该密码的密钥版本。一个我们称为 EncryptionKeyManager 的类维护了一组加密密钥(按创建时间排序)。无论何时解密一个字符串,都会使用用于加密的密钥(如果它仍然可用)。加密一个字符串时,将使用最新的密钥。当服务器启动时,它们从内存中读取密钥库的最新版本,进而获取所有当前密钥。在一次加密由于缺少密钥版本而失败时,CustomPasswordEncryptImpl 类将自动重新加载密钥库,查看是否有更新的密钥可用。如果添加了一个新加密密钥(且 DMgr 已重新启动),但应用服务器未重新启动,则可能出现这种情况。因此,我们的解决方案不要求在初始配置后重新启动应用服务器,以便让用于加密的密钥的更改生效。

强密码算法显然是此解决方案的一个关键需求。因此,我们在密码算法使用方面做出以下决策:

  • 我们使用了 Java JCEKS 密钥库提供程序,因为它能够存储对称密钥。
  • 我们使用了一个 Java JCE 密码系统,它使用具有密码反馈模式 (Cipher Feedback Mode) 的 AES 加密。我们不使用任何填充码,以避免向密码增添字符。供程序字符串为 AES/CFB/NoPadding(请参阅 JCE 文档 )。
  • 因为我们使用了 CFB 算法,所以我们还必须存储用于加密数据的初始化矢量;在每次使用一个密码系统加密密码时,我们允许 JCE 运行时创建一个随机初始化矢量。然后,我们将该矢量与密码存储在一起,用于在解密之前初始化密码系统。对每个密码使用一个独立的矢量,可限制它的重用并改善加密的安全性。即使同一个密码使用相同的密钥加密,得到的加密数据也可能明显不同。
  • 我们对 AES 加密使用 128 位密钥长度。更长的密钥长度需要特殊的 JDK JCE 管辖文件。这些特殊文件受美国联邦出口法律限制。给定加密的数据量和方法存在内在不足(将解密密钥存储在同一个文件系统上),我们不相信更长的密钥会带来任何显著的安全改进。
  • 我们在加密之前向每个密码的开头添加随机的 “盐”,以便进一步随机化存储的信息,使解密更加困难。

我们选择使密钥库、算法或加密类型变得不可配置,因为这么做会大大增加实现解密的复杂度,而且还会增加有人意外地配置非常弱的密码存储的可能性。因为所有配置信息都由一个类管理,任何能访问源代码(且具有合适的密码学技能)的人都可以更改代码,以便使用其他算法或配置。

在添加对密码加密的支持时,要考虑的一个明显问题是这可能对性能有何影响。当然,加密的成本很高,而且执行加密操作可能对应用程序的性能产生严重的影响。幸运的是,WebSphere Application Server 大胆地(在内存中)缓存了已解码/解密的密码。因此,尽管在启动服务器时(在它们读取密码时)以及在执行会影响密码的管理性更改时会有细微的性能开销,但运行时性能应该不会受此解决方案影响。

最后一个担忧涉及到将密码保存在内存中。不幸的是,尽管该担忧是合理的,但此问题没有可行的解决办法。根据 J2C 规范的要求,对一个资源的每个请求必须首先联系一个登录模块,以获取后端资源的凭据。该登录模块必须提供明文密码,以便底层资源可以使用它(这仅适用于需要密码的资源)。如果密码未以解密形式存储在内存中,那么从每个应用程序对每个资源上的 getConnection() 的调用都会对密码解密。这可能具有很大的性能影响。因为从一个进程的内存映像获取密码并不容易,考虑到该方法具有切实的性能优势,我们认为此风险是可接受的。

回页首

安全影响

如上所述,一定要记住,本文中描述的方法仅能稍微增加 WebSphere Application Server 环境的安全性,使通过另一次文件窃取来获取包含系统密码的文件变得更困难,而且文件遍历和窃取只是最明显的攻击矢量,其他攻击矢量不只是可能存在,而是一定存在。使用此增强之前,攻击者需要窃取一个密码包含文件,然后确定如何撤销 XOR 和 base64 编码。使用此特性时,攻击者必须窃取密码包含文件和加密密钥文件(这些文件必须位于机器上且必须具有与密码文件相同的读取访问权限)。然后,攻击者需要结合使用这些文件来解密密码。尽管不是没有意义,但对拥有恰当技能的人而言不一定困难。此解决方案的辅助价值是,在 WebSphere Application Server XML 配置文件与第三方共享时,将密码存储为加密形式不会阻止这些第三方确定嵌入在 XML 配置文件中的真实密码值。当然,前提是没有为第三方提供加密密钥的副本 - 这正是此解决方案将加密密钥存储在 XML 配置树外的原因。

正如本文最初发表时所说的,缺点是加密密钥带来了安全性更强的幻觉,这可能导致安全的错觉,使系统并不比简单地采用密码编码更安全。密码加密必须与一组全面且深入的安全策略、过程和评审或审计相结合。

而且,仍然需要记住的是,坚决的攻击者仍可能成功,甚至在您加密了密码时。

备份系统时,应考虑到备份同时包含加密的密码和解密密钥的事实。要实现最高的安全性,您应小心保护这些备份,甚至可以考虑将解密密钥存储在一个单独的备份上。如果选择后一个选项,一定要小心不要丢失这些密钥。没有解密密钥,密码将无法恢复!

回页首

可用性影响

决定使用秘密密钥加密密码,可能导致在丢失加密密钥时整个单元发生不可恢复的宕机。因此,在执行任何密钥管理操作之前,请备份您的单元,并在执行任何密钥管理活动时小心谨慎,这至关重要。如果某项操作导致仍在使用的加密信息丢失, 则无法在没有备份的情况下恢复

回页首

管理密钥:passmgr 实用程序

有一个简单的命令行实用程序 (passmgr.bat/sh) 可用来管理加密数据。启动脚本具有 UNIX® 和 Windows® 版本。passmgr 脚本遵循记录在案的标准的 “瘦客户端” 启动方法。

将 passmgr.bat/sh 复制到某个目录,并通过编辑该脚本为 WASHOME 指定正确的值之后,只需使用 passmgr.bat/sh 即可启动该工具,例如:

passmgr.bat

在大多数情况下,您可能希望提供该工具应使用的 WebSphere Application Server 配置文件的名称。如果未指定配置文件,将使用默认的配置文件。要指定一个配置文件,可使用 profileName 选项来启动 passmgr.bat。例如:

passmgr.bat -profileName Dmgr01

指定配置文件名称后,还有许多额外的可选参数,以及强制命令。下面列出了可用的命令,如果尝试运行该工具而不提供命令,您会获得一条给出了可用选项的错误消息:

清单 2

passmgr.bat No arguments specified Usage:  <command> [-dir <dir>] [-key <key#>] [-host <dmgr host>] [-port <dmgr port>] [-trace]   where <command> is one of:    create - create keyfile    addkey - add a key to keyfile    info - print information about a keyfile    deletekey - delete a key from keyfile    scanall - scan/read all passwords (may aid in debugging app server issues    forceencrypt - force the reencryption of all existing passwords    changemasterkey - change the master key protecting the keyfile 

可选的参数具有以下含义:

  • -dir:为密钥文件指定一个备用的根。如果希望创建一个密钥文件,但不希望更新当前配置文件所使用的密钥文件,这很有用。它很方便用于测试。
  • -key:对于需要一个键码(例如 deletekey)的命令,这就是键码。
  • -host:对于与 dmgr 通信的命令(例如 scanall 和 forceencrypt),您可指定一个非默认的 dmgr 主机名。默认值为 localhost。
  • -port:对于与 dmgr 通信的命令(例如 scanall 和 forceencrypt),您可指定一个非默认的 dmgr 端口。默认设置为 8879。
  • -trace:将跟踪信息输出到控制台,以表明管理工具在做什么。

回页首

结束语

IBM WebSphere Application Server(和构建于 WebSphere Application Server 之上的产品)将系统帐户密码存储在 WebSphere Application Server 配置文件结构中的各种文件中。这些密码已编码,而没有加密。加密这些密码不会增加针对某些漏洞类型的安全性。

WebSphere Application Server 提供了一个 SPI 来自定义这些系统密码的处理。本文介绍了 IBM WebSphere 软件服务部提供的此 SPI 的一种自定义实现。

如果有意部署这个来自 IBM WebSphere 软件服务部的自定义实现,或者有兴趣了解 WebSphere Application Server 安全性的更多信息,请联系 IBM WebSphere 软件服务部 来探讨与安全顾问合作的可能性,或获取 WebSphere Application Server 安全机制中一个自定义的现场类。该类涵盖了深入的安全性增强、自定义身份验证、集成、单点登录和其他各种相关主题。

回页首

致谢

感谢我的同事 Bill O’Donnell、Tom Alcott、Simon Kapadia、T. Rob Wyatt、Pete Neergaard、David Mundhenck 和 Paul Glezen 提供宝贵的建议和帮助。

特别感谢 Keys Botzum 编写的最初材料,以及上述文本的一个重要部分的原始草案。

正文到此结束
Loading...