Jboss 5.1.0基于密码的加密是否安全?

时间:2017-06-30 13:53:12

标签: security jboss cryptography

我正在使用基于密码的Jboss 5.1.0加密来保护我们的服务器。

我已阅读RFC的部分内容:

https://tools.ietf.org/html/rfc2898

我已经多次阅读了几个Jboss文档:

https://docs.jboss.org/jbosssecurity/docs/6.0/security_guide/html/Encrypting_Data_Source_Passwords.html(这是6.0,但适用于5.1.0)

现在,让我解释一下我的问题。

在上面列出的官方JBoss文档中,他们将“安全身份”加密视为安全。哎呀,这是在文件中。 更糟糕的是,我见过其他人就Stack Overflow如何使用此提出问题。 这不安全。为了使其安全,必须编写自己的加密类来覆盖org.jboss.resource.security.SecureIdentityLoginModule。

我能够通过快速谷歌搜索“Decrypt Jboss 5.1.0密码”来证明这一点,第一个结果是使用官方Jboss文档中推荐的方法解密Jboss密码的jar文件。

输入基于密码的加密。

知道我已经在第一种方法中发现了安全漏洞,我已经穿着从这个文档中获取建议 - 如果你错了一次,你可能错了两次。但是,似乎我没有必须使用方法2:基于密码的加密。

我担心的是,文档让我生成一个'master.password'文件。我假设这是RFC中提到的派生键函数。但是,我不确定。

总而言之,我的直觉告诉我: 你让我在我的服务器上存储了一个master.password。包含派生密钥功能的master.password文件可以被某些代码用于简单地解密我的加密密码。那是因为我在其他文件的其他地方指定了盐和迭代。

这整个过程看起来像是一个数学函数。在我看来,它看起来像这样:

? = DerivedKeyFunction(Salt,Iterations,Password)

但对于黑客来说,它看起来像这样:

EncodedPassword = DerivedKeyFunction(Salt,Iterations,?)

我声称自己既不是密码学家也不是Jboss专家,但我的直觉告诉我,黑客需要做的就是查看Jboss源代码(据我所知是开源代码)并做一点使用server.password文件获取密码的逆向工程。

所以我的问题是:Jboss上基于密码的加密有多安全(假设黑客获得了对服务器的访问权限)?有没有人真正研究过这个?

------------ 编辑 -----------------

澄清: 这是JBoss连接到我们的数据库。这不是最终用户登录Web应用程序上的用户帐户。

JBoss使用master.password(或server.password ...它只是一个文件名),其中包含某种加密字符串。我不确定这里有什么,它没有详细记录(或者可能是,我只是不明白)。

遵循配置后,永远不会再输入密码。我不明白这是多么安全。我猜我可以以某种方式使用在步骤1中创建的server.password文件来解密我的数据库密码。有人还没有编写一个方便的jar文件。但是代码是开源的,所以我猜想合适的人知道如何轻松地做到这一点。

由于我看到人们在堆栈溢出时使用的可怕设置数量,我正在分享这些步骤。步骤如下:

1)从jboss / common / lib文件夹中,创建server.password文件。放在server / conf目录中。:

    java -cp jbosssx.jar org.jboss.security.plugins.FilePassword <8Charactersalt> <iterationsMoreThan1000> <aLongRandomPassword> server.password
    #outputs server.password file which contains encrypted string.

2)加密数据库密码

    java -cp jbosssx.jar org.jboss.security.plugins.PBEUtils <8Charactersalt> <iterationsMoreThan1000> <aLongRandomPassword> <databaseConnectionPassword>
    #outputs encrypted DB Password

3)删除用户名&amp;密码&amp;更新数据源XML

    <security-domain>EncryptedMySqlDbRealm</security-domain>
    <depends>jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword</depends>

4)将Mbean添加到数据源XML。它指定server.password文件,salt和迭代。

<mbean code="org.jboss.security.plugins.JaasSecurityDomain"
    name="jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword">
  <constructor>
    <arg type="java.lang.String" value="ServerMasterPassword"></arg>
  </constructor>
  <!-- The opaque master password file used to decrypt the encrypted database password key -->
  <attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/server.password</attribute>
  <attribute name="Salt">${8Charactersalt}</attribute>
  <attribute name="IterationCount">${iterationsMoreThan1000}</attribute>
</mbean>

5)添加应用程序策略以登录配置XML。指定要加密的用户名,加密密码和数据源。应用程序策略和数据源之间存在1对1映射,因此如果您有两个数据源,则表明您还需要2个应用程序策略。否则你会在启动jboss时遇到错误。

<application-policy name="EncryptedMySqlDbRealm">
  <authentication>
   <login-module code = "org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule"
              flag = "required">
     <module-option name = "username">${DatabaseUsername}</module-option>
     <module-option name = "password">${EncryptedPassword}</module-option>
     <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=${DataSourceNameFromDatasourceXML}</module-option>
     <module-option name = "jaasSecurityDomain">jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword</module-option>
   </login-module>
  </authentication>
</application-policy>    

2 个答案:

答案 0 :(得分:0)

首先,一个问题:我对你所指的JBoss系统一无所知。但我相当确定系统要求您在我的服务器上存储master.password。&#34;但是,我对加密非常熟悉,可以提供这样的解释:

您希望存储一些纯文本数据并使用密码进行保护。因此,您要求用户输入密码,加密密码并存储加密文本(调用此密码&#34; cipher-text&#34;)然后丢弃密码。当用户想要检索它时,您要求输入密码,然后解密&#34; Cipher-Text&#34;。如果密码正确,您将返回原始纯文本。

加密(和解密)过程需要密钥。这是数值,而不是密码。因此,您需要一种从某些文本Pass-Phrase 派生键值的方法。 DerivedKeyFunction执行此操作。返回的结果不是编码密码。它是传递给加密/解密过程的Key值。

因此,您要求用户输入Pass-Phrase,然后调用DerivedKeyFunction获取Key-value,然后将纯文本加密为Cipher-Text(使用 ),存储生成的密文,然后丢弃密码短语和密钥。 要解密,你要求Pass-Phrase,重新获得密钥,然后解密。

基本上,DerivedKeyFunction是一个Hash函数(或进程);你用它来转换&#34; Pass-Phrase为加密过程可以使用的数值。

现在,您将注意到DerivedKeyFunction的其他两个参数:&#34; Salt&#34;和#34;迭代&#34;。这些都是增加攻击数据难度所必需的。 &#34;迭代&#34; (显然)指定重新散列Pass-Phrase的次数。并且&#34; Salt&#34;在这个迭代过程中注入一个随机数。 希望你现在看到这些是你需要用密码文本存储的两个值。无论何时您想从Pass-Phrase中获取Key,您每次都必须以相同的方式执行;这意味着迭代相同的次数注入相同的次数&#34;盐&#34;值。

所以,现在您的流程是:

1)选择随机盐值(是的,随机数)。

2)决定迭代计数,例如100,000。 (这应该是一个很大的数字,所以DerivedKeyFunction需要很长时间;稍后解释一下)

3)向用户询问Pass-Phrase。

4)呼叫DerivedKeyFunction将Pass-Phrase,随机Salt值和100,000交给它。这将返回一个键值(由这3个参数隐含)。

5)使用键值将纯文本加密为密文。

6)存储密文盐值迭代次数(100,000)

7)丢弃Pass-Phrase和Key-value。

要解密:

1)要求传递短语。

2)致电DerivedKeyFunction,将Pass-Phrase,存储的 Salt值和存储的迭代计数交给它。如果Pass-Phrase正确,则返回相同的(正确的)Key-value。

3)使用键值将密码文本解密为纯文本。

好的,为什么选择一个大数字来进行迭代计数呢?好吧,攻击者只需在密码后尝试密码,直到他们成功解密密文。但他们每次尝试都必须致电DerivedKeyFunction ,他们必须使用您加密数据时使用的正确的 Salt 值和迭代次数。并且,是的,因为你必须存储它们供你使用,攻击者才会知道它们是什么;但他们仍然需要一遍又一遍地呼叫DerivedKeyFunction。因此,您应该看到,迭代计数越高,攻击者可以尝试的每秒尝试次数就越少。

虽然您没有提及它,但在使用CBC(密码 - 块链)类型加密算法时,还有另一个参数称为IV或初始化向量。该值是加密/解密的输入,作为Key的伴随。由于它与上述过程有关,因此将其视为密钥的扩展:使用的DerivedKeyFunction应提供键值和IV值。并且,与Key-value一样,IV值永远不会被存储,并且会在丢弃Key-value的相同点处被丢弃。

答案 1 :(得分:0)

听起来你只想混淆密码。加密它只是使这个循环过程:您需要选择一个密码来加密您将用于加密密码的密码.......

Simply Base-64编码。或者其他类型的(非加密)编码。