毫不妥协地将加密添加到快速数据库

对好奇如何在高性能系统中实现强大的加密功能的人特别感兴趣。 它也适合那些只想进一步了解强加密的工作原理以及所有部分如何组合在一起的人。

介绍

确保系统安全非常困难 大型和广泛使用的系统的数据泄露,例如Adobe,Anthem,eBay,Equifax,Home Depot,JP Morgan Chase,Marriott,Sony,Target,Uber,VeriSign,Yahoo,美国人事管理办公室,甚至是很好的数据泄露像RSA Security这样的安全公司已经花费了数十亿美元,并损害了超过10亿用户的隐私或身份。

每个人都说他们想要更安全的系统,但人们不喜欢使用速度较慢或难以使用的系统,而使系统更安全可能会增加延迟并降低便利性。 当人们避免使用安全的系统,而是选择安全性较低但使用起来更快或更容易的系统时,这显然是很糟糕的。

因为数据库存储了我们最需要保护的数据,所以它们是安全难题的主要部分。 我们如何在不过度影响速度或可用性的情况下向数据库添加强加密? 研究各种公司如何做到这一点可以有所帮助。

毫不妥协地将加密添加到快速数据库

ger,快速数据库

本文研究了Dgraph Labs的团队如何将数据加密添加到Badger (一个非常快速和可靠的开源数据库)中。 已经在Github上超过7.3K明星和超过850项目,包括用于IPFS和尤伯杯的 最著名的是UsenetExpress ,它使用Badger存储PB的数据。

ger是一个键值数据库 (KVDB)。 KVDB将数据存储在关联数组(也称为对象,字典,映射或哈希表)中。

毫不妥协地将加密添加到快速数据库

KVDB之所以受欢迎,是因为它们是最简单,最快的数据库之一,并且易于学习,因为它们使用的是大多数编程语言中常见的数据结构。

KVDB非常适合在云计算中使用,并且Badger对于云使用特别快,因为它已针对典型的云硬件 (尤其是SSD存储) 进行了充分优化 与其他流行的KVDB相比,在此类硬件上提供了出色的性能

团队面临的挑战是弄清楚如何在不妥协的情况下实施加密。 我们知道这是有可能的,因为公司能够(最终)弄清楚如何向http添加加密(创建https),而又不会使最终用户的速度明显变慢。

正如我们将看到的,Badger的高级实现对添加加密的方式产生了积极的影响。

实施

毫不妥协地将加密添加到快速数据库

即使没有加密,Badger的实现也使其更安全,并且不易出现可能危及安全性的错误。 它是用Go语言编写的,该语言是由Google的一个小型团队开发的,其中包括Ken ThompsonUNIX正则表达式Plan 9UTF-8 )。 Go的目标是通过增加内存安全性,自动垃圾回收,安全并发以及跨网络计算机的多处理来改进C语言。 ger已迅速成为用Go编写的最活跃的KVDB。

ger设计为可在其他项目中使用。 它被实现为可嵌入的库 ,而不是单独的服务。 这提高了安全性和速度。 如前所述, Badger是开源的 ,因此可以对其进行检查以找到不安全的代码 ,甚至可以对其进行修改以满足项目需求。

ger也很可靠。 它通过使用多版本并发控制( MVCC )运行并发ACID事务来确保可序列化快照隔离(SSI)。 在面对进程,文件系统甚至硬件崩溃时,Badger具有弹性。

将键与值分开

Badger的实现的高级功能是拆分键值对,并将值与键分开存储。 **通常是短字符串,因此将它们存储在一个位置可以大大加快搜索**的速度。 **通常不会像值那样频繁地更改,因此可以对**文件(包括用于查找**的哈希表)进行更广泛的优化,以进一步提高性能。

另一方面,值通常比键更大,并且更改次数比键多。 例如,值可以是在编辑文档时更新的整个文档。 多个值存储在值日志文件(vlog)中。 与每个键关联的是指向其值指针,该指针由vlog文件ID,文件中值的偏移量和值的大小组成。 请注意,作为优化,小于用户指定大小(默认为32个字节)的值将与其关联的键一起存储,而不是存储在vlog文件中。

毫不妥协地将加密添加到快速数据库

假设每个键16个字节和每个值指针16个字节,则单个64MB文件可以存储两百万个键值对 它足够小,几乎可以放入任何计算机的RAM中,这意味着通常可以在高速存储器中进行键搜索,这可以比搜索二级存储快几个数量级。

分层Bad

除了单独用作数据库之外,Badger还可以用于实现更复杂的数据库。 尤其是,Dgraph Labs 创建了Badger,专门用于其旗舰产品Dgraph (第一个本地GraphQL数据库)中。 Dgraph是开源的,可以高度扩展到固定计算机或云中的大量服务器。

毫不妥协地将加密添加到快速数据库

将Dgraph放在Badger之上可以带来很多好处,尤其是关注点分离 Dgraph使用Badger来存储用户的数据,因此Dgraph根本不关心数据存储(包括存储数据的加密)。 由于Badger是一个较小的独立系统,因此可以更轻松,更自信地构建,测试和验证诸如加密之类的新功能。 Badger透明地为Dgraph或使用Badger存储数据的任何其他系统提供加密。

这类似于Internet协议套件 ,后者在诸如IP的较低层协议的基础上提供诸如TCP的高层协议。 这允许在IP之上构建其他高级协议(例如UDP,DCCP,SCCP,RSVP)。 对IP进行改进(例如从IPv4到IPv6 )时,更高级别的协议都可以轻松利用它们。

先进的加密标准

向Badger添加加密时,最容易做出的决定之一就是选择备受推崇的AES加密算法,该算法由美国NIST标准化,并由MongoDB,SQLite和许多其他数据库和系统使用。 AES已成为行业标准,因为它是用于加密数据的最安全且使用广泛的算法。 广泛使用对于加密标准至关重要,因为它们有助于发现和修复潜在的安全漏洞。

毫不妥协地将加密添加到快速数据库

AES是对称的; 相同的加***用于加密和解密数据。 ger支持**轮换以进一步保护对数据的访问。 这使Badger可以用于需要满足各种数据保护法规和要求的系统中,包括GDPR,HIPAA和PCI DSS。

按键旋转

加密和解密数据需要加***。 AES**有三种大小:128、192和256位。 使用哪种大小实际上并不是很重要 ,因为128位**的强力**将占用全球最快的计算机超过百亿亿(10到17次幂)年。 即使您可以让一千万台超级计算机一起工作来完成**,它仍然需要比当前宇宙时代更长的时间。

更重要的是保持**的安全性,避免**泄漏 显然,加***必须由用户安全地存储,并且不容易猜测。 但是,还有其他来源的**泄漏。 例如,“边信道”攻击表明 ,可以通过测量来自计算机的电磁辐射(使用价格约为200美元的设备)在短时间内**最安全的(256位)AES**。可以放进外套的口袋里。 进行加密的计算机必须在物理上安全,以防止发生这种情况。

毫不妥协地将加密添加到快速数据库

即使没有物理访问,如果过于频繁地使用同一**,攻击者也可以通过已知的方法通过分析使用该**加密的大量数据来确定**的值。 为了避免这种情况,必须定期更换钥匙,这称为钥匙旋转。 但是,更改**后,必须使用旧**解密现有的加密数据,然后使用新**重新加密。 这些计算会严重降低加密数据的性能。

一键统治一切

Badger不是直接使用AES加***来加密数据,而是使用两种类型的**:1)用户提供的称为主**的 AES加***用于加密数据**。 2) 数据**由Badger自动生成,并用于加密和解密磁盘上的数据。 每个加密的数据**与加密的数据一起存储在磁盘上。

毫不妥协地将加密添加到快速数据库

默认情况下,Bad每十天旋转一次数据**,但是用户可以更改此**。

用户提供的主**的长度必须为16、24或32个字节。 这决定了使用哪种版本的AES加密(分别为AES-128,AES-192或AES-256)。请注意, 切勿使用可预测的字符串作为主**。 如果您具有密码管理器(例如1Password,LastPass等),则可以使用其内置的密码生成器来生成强加***。 即使您没有密码管理器,也可以使用信誉良好的在线密码生成器(例如1Password)生成主**。

您应该定期旋转主**。 幸运的是,由于主**仅用于加密数据**,因此与存储在数据库中的数据相比,这些数据**(甚至一起)要小得多,因此不需要频繁旋转主**(如数据**)来防止钥匙泄漏。 更好的是,当旋转主**时,仅需要使用旧的主**对数据**进行解密,然后使用新的主**对数据**进行重新加密。 这比重新加密磁盘上的所有数据快得多。

避免加密重复项

当使用数据**对存储在数据库中的数据进行加密时,同一数据通常会在数据**的轮换期限到期之前进行多次加密。 使用相同的数据**对相同的数据进行加密始终会生成要存储在数据库中的相同的加密文本。 这提高了攻击者对原始明文数据进行反向工程的能力。

为了降低原始数据的可预测性,Badger引入了一种标准的加密技术,该技术不会直接使用数据**来加密数据。 相反, Badger会生成一个随机的16字节数组,称为 初始化向量 (IV)。 数据**用于加密IV,然后将加密的IV与用户数据进行XOR运算,结果存储在磁盘上。 这意味着即使对同一块进行多次加密,IV的随机值也可以确保每次存储的文本都不同。

毫不妥协地将加密添加到快速数据库

除了降低数据可预测性之外,IV的使用还提高了性能,因为XOR操作比直接在要加密的数据上运行AES加密算法要快得多。 增加的安全性和性能的开销是每个16字节IV使用的额外存储空间。 因此,使用IV的潜在问题是它可能导致数据膨胀。

减少IV的存储开销

包含**的文件每个都分为几个块,每个块的大小为4KB。 ger使用唯一的IV加密每个这些块,并将IV以明文形式存储在加密块的末尾。 16B IV在4KB块上的存储开销为0.4%,这是合理的。

请注意,以明文形式存储IV仍然是安全的。 假设**者可以访问IV和加密的块。 要解密该块,他们需要使用数据**对IV进行加密(以将加密后的数据异或为纯文本)。 但是要访问数据**,他们需要使用主**对其进行解密。 如果主**是安全可靠的,那将是不可能的,这会使工作徒劳。 因此,仅知道IV不足以解密数据。

避免在每个值上附加一个16字节IV的膨胀

接下来,我们需要加密存储在vlog文件中的值。 使用与每个键关联的值指针从vlog文件中分别读取每个值,该指针存储vlog文件ID,文件中的偏移量和值的大小。 如果我们一次加密整个块,那么一个块中有多个值将导致性能显着下降,因为需要解密大量的额外数据才能读取单个值。

由于经常需要单独访问值,因此我们决定分别加密每个值 由于要求每个加密值具有其自己的随机IV,因此,每个值使用一个IV将为每个值增加16B的开销。 对于包含10,000个条目的vlog文件,用每个值存储一个IV将需要160,000字节,这不好。

这并不那么糟糕,因为小值直接存储在**文件中,而不是指针中,并且该值连同其**一起被解密。 但是即使进行了这种优化,除非所有值都非常小,否则容易想象每个值只有一个IV可能会使vlog文件的大小增加一倍。 幸运的是,我们提出了一个更好的解决方案。

为了优化vlog条目的加密, Badger使用了一种独特的技术 Badger不会生成一个16字节的IV并将其存储在vlog中每个值的末尾,而是生成了一个12字节的IV用于vlog文件中的所有值。

同时,Badger附加了4个字节,这些字节包含vlog文件中值的偏移量,这些字节一起构成了所需的16个字节的IV。 对于解密,可从与每个**一起存储的(解密)值指针中获取4字节的vlog偏移量。 每个vlog的12字节IV都是唯一的,而在单个vlog文件中4字节的偏移量也是唯一的,因此每个复合16字节IV也是唯一的。

毫不妥协地将加密添加到快速数据库

该技术为vlog文件中的每个值节省了16个字节的磁盘空间。 而是,此技术每个vlog文件仅需要12个字节,而不管文件中值的数量。 这比**文件节省的更多。

结论

我们使用已建立并证明有效的标准和最佳做法,将加密功能添加到Badger中,并以与Badger现有功能和优势完美结合的方式实施。 最重要的是,加密的添加并没有明显减慢Badger的速度,使其使用困难或不便或显着增加了使用的存储空间。

Badger是开源的,并且已被用作许多大型系统的存储引擎,现在它包括免费的加密功能。 我们希望Badger可以使更多项目变得更容易,尤其是那些需要安全存储加密数据的项目。

有关 Badger的 更多信息 ,请参见 Dgraph博客条目 ,包括有关 Badger中加密的内容

From: https://hackernoon.com/adding-encryption-to-a-fast-database-without-compromise-5u3b3yth