On Sun, Jun 5, 2016 at 2:20 AM, Pierre Joye <pierre....@gmail.com> wrote:
> > On Jun 5, 2016 5:15 AM, "Stanislav Malyshev" <smalys...@gmail.com> wrote: > > > > > The stated goal is "You shouldn't need a Ph.D in Applied Cryptography to > > build a secure web application." I fully agree with this goal. I however > > feel that current implementation, while making admirable progress > > towards this goal, still needs some work to actually achieve it. > > I fully agree with you. As much as I think we need something like that, I > think these are stopping points. > > I would very interested to hear from Scott about these questions and the > low level nature of the APIs make it not as friendly or future proof as it > could. > > Cheers > Pierre > Hi Pierre, My position on the low level nature of libsodium's APIs is as follows: That sounds like a call to action for https://wiki.php.net/rfc/php71-crypto rather than a point of concern for adopting libsodium. Compare the following two snippets which accomplish the same "goal" (anonymous public-key encryption). <?php /** * OpenSSL -- since the Diffie Hellman features in ext/openssl kind * of suck, I'm going to use RSA to encrypt the AES key using the * recipient's public key. */ ## ENCRYPTION ## $message = 'Prime Numbers Rock!'; $publicKey = openssl_pkey_get_public('file://path/to/public_key.pem'); $aesKey = random_bytes(32); // Basically a poor-man's HKDF by just using HMAC $keyE = hash_hmac('sha256', 'Encryption Key', $aesKey, true); $keyA = hash_hmac('sha256', 'Authentication Key', $aesKey, true); $iv = random_bytes(16); $ciphertext = openssl_encrypt($message, 'aes-256-ctr', $keyE, OPENSSL_RAW_DATA, $iv); $mac = hash_hmac('sha256', $iv . $ciphertext, $keyA, true); $combined = $mac . $iv . $ciphertext; $rsaCipher = ''; openssl_public_encrypt($aesKey, $rsaCipher, $publicKey, OPENSSL_PKCS1_OAEP_PADDING); $sendMe = $rsaCipher . $combined; ## DECRYPTION ## $privateKey = openssl_pkey_get_public('file://path/to/private_key.pem'); $rsaPart = mb_substr($sendMe, 0, 256, '8bit'); // Assuming 2048-bit RSA $aesPart = mb_substr($sendMe, 256, null, '8bit'); $mac = mb_substr($aesPart, 0, 32, '8bit'); $iv = mb_substr($aesPart, 32, 16, '8bit'); $cipher = mb_substr($aesPart, 48, null, '8bit'); openssl_private_decrypt($rsaPart, $aesKey, $privateKey, OPENSSL_PKCS1_OAEP_PADDING); $keyE = hash_hmac('sha256', 'Encryption Key', $aesKey, true); $keyA = hash_hmac('sha256', 'Authentication Key', $aesKey, true); $calc = hash_hmac('sha256', $iv . $cipher, $keyA, true); if (!hash_equals($calc, $mac)) { throw new Exception('MAC validation failure'); } $decrypted = openssl_decrypt($cipher, 'aes-256-ctr', $keyE, OPENSSL_RAW_DATA, $iv); var_dump($decrypted); // string(19) "Prime Numbers Rock!" Can you count the foot-bullets in that snippet that you'd need to be a cryptography engineer to successfully avoid? Demo: https://3v4l.org/nYVPf Here's a congruent implementation in libsodium: <?php /** * Libsodium */ ## ENCRYPTION ## $message = 'Prime Numbers Rock!'; $bob_public_key = "... populate here ..."; $nonce = random_bytes(24); $sendMe = \Sodium\crypto_box_seal($message, $bob_public_key); ## DECRYPTION ## $bob_kp = "... populate here ..."; $decrypted = \Sodium\crypto_box_seal_open($sendMe, $bob_kp); var_dump($decrypted); // string(19) "Prime Numbers Rock!" (No demo available, as 3v4l doesn't have ext/sodium installed.) Libsodium already knocks it out of the park compared to OpenSSL and Mcrypt. If we want to talk about a higher-level abstraction-- such as what's provided by paragonie/EasyRSA + defuse/php-encryption or paragonie/halite-- I wholeheartedly endorse that discussion. But I don't think we should try to solve that problem with this particular RFC. In closing, I don't disagree that a simple crypto API is a good goal to have. I just think the ideal you're discussing is: A. Out of scope, and B. Kind of belittling to how much of an improvement libsodium is to what we already have. Further reading: http://framework.zend.com/security/advisory/ZF2015-10 Scott Arciszewski Chief Development Officer Paragon Initiative Enterprises <https://paragonie.com/>