当PHP 7.2在今年年底发布时,PHP将成为第一个在标准库中采用现代密码学模块的编程语言。
Scott Arciszewski采用了知识共享协议许可(Creative Commons License),经作者授权,InfoQ翻译本文如下。
现代密码学是什么?
现代密码学库往往满足以下两个条件:
使用用于抵抗边信道密码分析的快速原语(例如Timing Leak、Padding Oracle)。
显示高级API是简单的、缺省安全的。
安全原语
如果在OpenSSL和Golang中实现公钥加密和数字签名,则必须在RSA和NIST ECC之间进行选择。这两者都不是一个好选择。
很少有开发者可以正确获得RSA:e=d=1邀请开发者使用RSA-ECBPKCS1v1.5 padding
NIST的椭圆曲线加密算法
无效曲线攻击,如果攻击者提交不在曲线上的(x,y)坐标,则通过中国剩余定理泄漏您的密钥
在ECDSA的情况下(在RFC 6979之前),ECDSA签名的重复k值泄漏您的密钥
NIST曲线不是严密的
现代密码学需要使用安全原语。对于公钥加密,这意味着在RFC 7748和RFC 8032所描述的原语。对于对称加密,这意味着使用经过认证的加密算法。
NIST曲线(P-256等)不符合现代密码学原则(不过并不影响密码学库中使用这些算法)。
Libsodium的原语包括:
X25519(在Curve25519上的椭圆曲线的Diffie-Hellman)
Ed25519 (在Curve25519上的Edwards-curve数字签名算法)
Xsalsa20poly1305(经验证的对称密钥加密,在软件中表现良好,并且不具有cache-timing的脆弱性,如软件AES)
BLAKE2 (基于SHA3的入围者,在软件中执行速度比MD5快,但比SHA256更安全)
Argon2 (密码散列和密钥导出功能)
SipHash-2-4 (哈希表和类似数据结构的快速哈希)
ChaCha20-Poly1305 (具有相关数据的认证加密)
但你可能不需要担心这些细节,因为它也提供了一个……
简单和安全的高级API
为了促进libsodium中的公钥加密,您只需要按照以下去进行:
// Some example variables:
$alice_ecdh_secret =
"\x69\xf2\x08\x41\x2d\x8d\xd5\xdb\x9d\x0c\x6d\x18\x51\x2e\x86\xf0" .
"\xec\x75\x66\x5a\xb8\x41\x37\x2d\x57\xb0\x42\xb2\x7e\xf8\x9d\x8c";
$bob_ecdh_public =
"\xe8\x98\x0c\x86\xe0\x32\xf1\xeb\x29\x75\x05\x2e\x8d\x65\xbd\xdd" .
"\x15\xc3\xb5\x96\x41\x17\x4e\xc9\x67\x8a\x53\x78\x9d\x92\xc7\x54";
$message_keypair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
$alice_ecdh_secret,
$bob_ecdh_public
);
$plaintext = "This is a secret message for your eyes only.";
$nonce = random_bytes(24);
// And now for the actual public-key encryption step:
$ciphertext = sodium_crypto_box($plaintext, $nonce, $message_keypair);
解密信息:
$received = sodium_crypto_box_open(
$received_ciphertext,
$received_nonce,
$message_keypair
);
这对我意味着什么?
如果你使用PHP进行开发,并且当7.2发布时可以升级到新版本,你会享受现代加密作为语言本身的一部分带来的好处。现在可以设计使用Ed25519数字签名(例如用于自动安全更新)的软件,而不需要用户安装可选的PHP扩展。
我讨厌PHP,没有办法比$ favoriteLanguage更安全
已经出现了一堆响应我在推特上宣布RFC通过的信息。可是,大多数并非提议在这个问题上超越PHP语言。
然而,事实并非如此:
Go 1.8将在TLS堆栈中使用X25519和ChaCha20-Poly1305,但它在标准库中并不提供现代应用层加密。这意味着你也可以在 Go 中使用现代的TLS算法,但是如果你想要进行额外的数据加密操作,你需要在标准库之外引入其他第三方库。
大多数其他编程语言(Ruby、Erlang、Node.js)仍然只提供OpenSSL,它会误导开发者继续滥用RSA,在ECB模式下使用AES加密,并且永远不会验证它们的密文。此外,许多这些语言仍然使用OpenSSL的用户空间PRNG,并且不公开一个合理的API访问操作系统的CSPRNG。(PHP 7.0正在解决这个问题。)
PHP 7.2.0 版本中引入的现代密码学模块使其成为第一个在标准库中提供了现代密码学支持的编程语言。
如果你是一个热情的语言传道者,现在最好的事情是努力争取二次市场。看到大家放弃了RSA和foot-bullety ECDSA,我很高兴。