OpenSSL vs GPG 用于加密异地备份?

OpenSSL vs GPG for encrypting off-site backups?

考虑到在将存档推送到异地备份位置之前使用 GPG 和 OpenSSL 进行本地加密的选择,每种解决方案的优缺点是什么?

背景: 我目前管理基于 Ubuntu 14.04.1 的服务器基础架构,所有当前补丁可用时都会应用。

所有这些系统都是无头的,使用经过审查的预置种子和自动化工具自动构建,并且 运行 通过 KVM 在统一的基于 Intel 的硬件上的虚拟机中。

我们更喜欢Ruby,但更喜欢"doing things correctly"。由于这两者,我们选择 "backup" gem 作为创建我们想要保留的数据的加密存档的方法,因为它将为使用 Vagrant 的开发人员创建与在生产中相同的加密存档,无论其传输机制如何。

所有软件和配置都是通过 Puppet 管理的,因此这两个决定都不会对 "user experience" 或便利性产生任何影响。任一选项都将创建相关脚本来管理、验证或从创建的任何备份恢复。

鉴于此,当用于此目的时,任一加密选项相对于另一选项是否具有任何优势?

我会选择 GPG 进行文件加密,它经过数十年的安全测试加密,并且很容易拥有多个 "recipients"(备份密钥?)或带有 public 密钥的签名甚至服务器(如果它们有用的话)。

使用 GPG,所有简单的错误都是 avoided/fixed,它会选择更长的 "random" 密钥进行实际加密,并进行大量 "rounds" 以使其非常安全.

OpenSSL 应该 能够做所有相同的事情,(它自 1998 年以来一直存在,但如果版本号意味着什么它在 2010 年达到版本 1)但它非常容易犯一个可能会大大降低安全性的错误。来自 159K 信誉用户的 this post on security.stackexchange.com (from Jan 2013) and anotheropenssl enc 命令可能会留下一些不足之处:

The encryption format used by OpenSSL is non-standard: it is "what OpenSSL does", and if all versions of OpenSSL tend to agree with each other, there is still no reference document which describes this format except OpenSSL source code. The header format is rather simple:

magic value (8 bytes): the bytes 53 61 6c 74 65 64 5f 5f salt value (8 bytes)

Hence a fixed 16-byte header, beginning with the ASCII encoding of the string "Salted__", followed by the salt itself. That's all ! No indication of the encryption algorithm; you are supposed to keep track of that yourself.

The process by which the password and salt are turned into the key and IV is not documented, but a look at the source code shows that it calls the OpenSSL-specific EVP_BytesToKey() function, which uses a custom key derivation function with some repeated hashing. This is a non-standard and not-well vetted construct (!) which relies on the MD5 hash function of dubious reputation (!!); that function can be changed on the command-line with the undocumented -md flag (!!!); the "iteration count" is set by the enc command to 1 and cannot be changed (!!!!). This means that the first 16 bytes of the key will be equal to MD5(password||salt), and that's it.

This is quite weak ! Anybody who knows how to write code on a PC can try to crack such a scheme and will be able to "try" several dozens of millions of potential passwords per second (hundreds of millions will be achievable with a GPU). If you use "openssl enc", make sure your password has very high entropy ! (i.e. higher than usually recommended; aim for 80 bits, at least). Or, preferably, don't use it at all; instead, go for something more robust (GnuPG, when doing symmetric encryption for a password, uses a stronger KDF with many iterations of the underlying hash function).

man enc 甚至 "BUGS":

There should be an option to allow an iteration count to be included.