20199325 2019-2020-2 《网络攻防实践》综合实践

20199325 2019-2020-2 《网络攻防实践》综合实践

论文相关信息:

文章是:Mind Your Keys? A Security Evaluation of Java Keystores

这篇文章来自NDSS2018年的期刊当中。该篇论文主要进行的是一个测评,主要分析Java密钥库,考虑从oraclejdk和Bouncy Castle的七个密钥库实现,描述了各种密钥存储库如何通过基于密码的加密来加强存储密钥的机密性和完整性,并且我们研究了许多实现不符合最先进的加密标准。除此之外论文还研究了java密码库对离线攻击的抵抗力,发现对于不兼容的密钥库,暴力强制方法与最兼容的密钥库相比,速度要快一个数量级。当攻击者可以篡改密钥库文件时,某些实现更容易受到拒绝服务攻击,或者在最坏的情况下,易受任意代码执行的攻击。

论文主要所作工作:详细分析了Java生态系统中密钥管理的安全性,特别是Java密钥库的安全性。受密码保护的密钥库是在Java中安全地管理和存储加密密钥的标准方法:一旦用户(或应用程序)提供了正确的密码,密钥库中的密钥就变得可用并且可以于执行加密操作,如加密和数字签名。keystorejava类从实际的KeyStore实现中抽象出来,它可以是加密文件的形式,也可以是基于安全硬件的。
估计了采用率,并分析了Oracle JDK和广泛使用的密码库Bouncy Castle提供的七种不同Java密钥库的实现细节。keystore被数以百计的商业应用和开源项目所使用,评估方法包括GitHub代码托管服务,包括领先的web应用服务器和框架,例如Tomcat、Spring、Oracle Weblogic。此外在大型金融、政府和医疗保健公司的安全关键型定制Java软件中,keystore也是广泛应用,这就带来了大量的安全隐患。

密钥库的生成步骤:

密钥库的安全性是通过一个名为密钥派生函数(KDF)的函数F从密码派生出来的密钥下执行加密操作C来实现的。密码操作C的目的是保证所存储密钥的机密性和/或完整性。例如,基于密码的加密(PBE)方案用于保护密钥的机密性:在这种情况下,C通常是一个对称密码,因此密钥在存储到密钥库之前使用提供的密码进行加密。
为了检索和使用该密钥,密钥库实现将执行以下步骤:
(a)从用户处获取密码;
(b)使用F从密码派生加密密钥;
(c)通过c解密特定密钥库条目,并检索实际密钥材料。(请注意,可以使用不同的密码来保护不同的密钥和/或实现完整性。)
在大多数情况下,密钥库使用弱或自定义实现来实现密钥派生函数F,从而打开了密码暴力强制的途径。我们已经根据经验测量了攻击者在使用这些有缺陷的密钥库时达到的速度,并且我们表明,在某些情况下,暴力强制比基于标准机制的密钥库快三个数量级。我们甚至发现密钥库使用了弃用的密码RC2,使攻击者能够在几小时内使用标准桌面计算机暴力破解40位长的加密密钥

论文作者提出论文贡献

  1. 我们为受密码保护的密钥库定义了一个通用的威胁模型,并提取了一组重要的安全属性和任何安全密钥库都应该遵守的相应规则
  2. 我们对七个密钥库进行了深思熟虑的分析,报告了有关其加密实现的未记录细节,并根据我们提出的属性和规则对密钥库进行了分类
  3. 我们报告了所分析密钥库中未发布的攻击和弱点。对于每一次攻击,我们指出了相应的违反我们提出的属性和规则的行为,并给出了一个精确的攻击者模型
  4. 我们根据经验估计了由于糟糕的加密实现而导致的加速,并且我们表明,在某些情况下,这可以减少对最具抵抗力的密钥库的三个数量级的猜测时间,以及对于NIST建议的四个数量级的猜测时间;有趣的是,对Oracle JKS密钥库的攻击我们在本文中介绍的,以及我们之前在博客文章中提到的,最近被集成到Hashcat密码恢复工具中
  5. 在我们负责任的披露之后,我们讨论了Oracle和Bouncy Castle密钥库实现的安全性方面的进展。Oracle安全团队通过分配两个CVE ID来确认报告的问题

进行实验复现当中

首先需要提出作者使用java进行评测了七个密钥库,并且把他们列举出来,都是知名并且经常使用的密钥库

Oracle:

  • JKS(“ Java密钥库”,标准库中的默认密钥库,至少保留到JDK8_u144(2017年8月,作者将论文提交给NDSS 2018会议的时间)。
  • JCEKS(“ Java密码学扩展密钥库”)
  • PKCS12(PKCS#12的实现)

Bouncy Castle:

  • UBER(不是缩写)
  • 银行卡
  • BKS
  • BCPKCS12(Bouncy Castle PKCS12实现)

作者发现了几个漏洞。所有这些都在表II中以图形方式列出。

尤其是,JKS和JCEKS在(存储的密钥数据的)机密性和完整性(即在不了解授权方的情况下可以篡改存储的数据)方面容易受到攻击,甚至允许将恶意代码注入(和执行)到密钥存储中文件在某些情况下。并且他们已于2017年5月及时向Oracle和Bouncy Castle公开了他们的发现,并在其论文中记录了Oracle和BouncyCastle宣布的更新。

关于实验的复现:

伪代码的实现:算法1,JKS一站式破解

我们的再现目标是显示通过Focardi等人的算法(在本文中称为“算法I”)获得的蛮力加速。我们使用JDK 8_u144附带的“ keytool.exe”创建了一些易受攻击的JKS密钥库,在Java中实现了伪代码,并创建了两个字典来模拟暴力破解。

然后,我们对所有密钥库进行了攻击,并显示了传统的和优化的暴力破解尝试之间的时间差。我们没有使用Standard(封闭源)JKS库,而是使用Casey Marshall(rsdio@metastatic.org)的反向工程版本,我们在对我们有必要或有用的地方修改了此反向工程版本。

实验设置

实验内容

该实验包括两次攻击尝试。我们对“数据”目录中提供的每个键执行它们,并比较它们的速度。

在常规的攻击尝试中,我们对每个可能的密码执行标准的解密方法(REJKS.decryptKey)。

在优化版本中,我们对加密密钥的第一个20字节块中,执行已知明文攻击。

  • E是密钥的整个加密字节串,包括校验和和盐。这是从REJKS.getEncryptedPrivKey(String alias)获得的。
  • E1等于E的前20个字节块。
  • test_bytes是三个已知的明文字节XOR E1的前三个字节
  • temp等于所有X位RSA密钥的已知纯文本字节(即前三个字节)。由于它们根据密钥大小而有所不同,因此,我们为所有常规密钥大小创建了这些已知字节的哈希图。
  • W1是一个20字节的块,等于h(password || salt),其中“ h”是sha1,“ password”是当前尝试的密码。
  • 如果W1的前三个字节等于test_bytes(错误肯定值为2 ^ -24),则密码猜测是正确的

这应该快得多,因为一次密码尝试仅需要一个sha1摘要和三个字节的比较。

在IDEA中,可以看到一共有六个文件,其中outdata中包含所给密钥,且将输出自动输出至outdata中,main函数为主要运行主要针对的就是JKS的复现,所以只有REJKS的函数还有一个测试JKS是否成功的函数。FAILed和logger都是针对恢复密钥失败或者没找到密钥的函数。

构建实例,公有类REJKS进行密钥创建。

所依据的JKS伪代码进行构建。

硬件软件

我们的硬件:

该软件已成功在以下平台上运行:

  • 英特尔酷睿i7-6700HQ,8GB DDR4 UDIMM RAM(NON-ECC)Win10家庭版64位
  • 英特尔酷睿i5-4210U,12GB DDR3 USIMM RAM(NON-ECC)Win 10家庭版64位

我们的软件:

我们安装了作者使用的JDK版本:JDK8_144,以便使用它的“ keytool.exe”工具,该工具位于JDK的./bin目录中。

在使用过程中已经写好了bat运行脚本,只需要进行执行即可。

结果:根据密钥大小,加速速度介于一到两个数量级之间。作者的表达是正确的,即加速在很大程度上取决于密钥的大小。原因是传统的尝试必须对加密密钥流的每20个字节块进行解密,而单块破解方法的解密要花费固定的时间。

在实验数据集中,我们提供了两个密钥(“ key_2_1024.jks”和“ TestKeyStore_4.jks”),我们的字典包含两个密钥,该密钥产生相同的三个已知明文字节。由于校验和显示密码错误,因此测试程序将继续在字典中进行搜索,直到找到正确的密码为止。

结果输出显示在outdata文件中。

实验结果:



结果进行评估,个人没有七个密钥库,所以是原文中的结果对比:

posted @ 2020-07-05 17:13  20199325赵恩泽  阅读(268)  评论(0编辑  收藏  举报