Paragon Initiative Enterprises
PHP 7.2: The First Programming Language to Add Modern Cryptography to its Standard Library
Scott Arciszewski
Feb 12 '17
Last week, the voting phase closed on an RFC to add libsodium to PHP 7.2. The result was unanimous (37 in favor, 0 against).
When version 7.2 releases at the end of the year, PHP will be the first programming language to adopt modern cryptography in its standard library.
What is Modern Cryptography?
A cryptography library can be said to be modern if it meets two requirements:
- Uses fast primitives designed to resist side-channel cryptanalysis (e.g. timing leaks, padding oracles).
- Exposes a high-level API that is simple and secure-by-default.
Secure Primitives
If you implement public key encryption and digital signatures in OpenSSL and Golang, you're forced to choose between RSA and NIST ECC. Neither is a good choice.
- Very few developers can get RSA right:
- e = d = 1
- Invites developers to implement RSA-ECB
- PKCS1v1.5 padding
- NIST's Elliptic Curve Cryptography
- Invalid curve attacks, which gives away your secret key via the Chinese Remainder Theorem if an attacker submits
(x, y)coordinates that aren't on the curve - In the case of ECDSA (before RFC 6979), repeated k values for ECDSA signatures gave away your secret keys
- NIST Curves aren't rigid
- Invalid curve attacks, which gives away your secret key via the Chinese Remainder Theorem if an attacker submits
Modern cryptography requires the use of secure primitives. For public key crpytography, that means the primitives outlined in RFC 7748 and RFC 8032. For symmetric cryptography, that means using authenticated encryption at all times.
NIST curves (P-256, etc.) do not qualify as modern cryptography (although their presence in a library doesn't automatically disqualify either).
Libsodium's primitives include:
- X25519 (Elliptic Curve Diffie-Hellman over Curve25519)
- Ed25519 (Edwards-curve Digital Signature Algorithm over Curve25519)
- Xsalsa20poly1305 (authenticated symmetric-key encryption that performs well in software and doesn't have cache-timing vulnerabilities like software AES)
- BLAKE2 (based on the SHA3 finalist that performs faster than MD5 in software but is more secure than SHA256)
- Argon2 (password hashing and key derivation function)
- SipHash-2-4 (fast hash for hash tables and similar data structures)
- ChaCha20-Poly1305 (authenticated encryption with associated data)
But you'll likely not need to worry about these details, because it also provides a...
Simple and Secure High-Level API
To facilitate public-key encryption in libsodium, you just need the following:
// 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);
To decrypt a message:
$received = sodium_crypto_box_open(
$received_ciphertext,
$received_nonce,
$message_keypair
);
What does this mean for me?
If you develop in PHP and can upgrade to 7.2 when it comes out, you get to enjoy modern cryptography as a part of the language itself. It will now be possible to design software that uses Ed25519 digital signatures (e.g. for automatic security updates) without requiring users to install an optional PHP extension.
I hate PHP, there's no way it's more secure than $favoriteLanguage
This has come up a bunch in response to my tweet announcing the RFC passing. However, most of the languages that were proposed as being ahead of PHP on this issue weren't.
Here are the facts:
Go 1.8 will use X25519 and ChaCha20-Poly1305 in its TLS stack, but it doesn't offer modern application-layer cryptography in its standard library. Which means if you want to use modern TLS, you can, but if you want to encrypt data at rest, you have to either go outside the standard library or use 90's era public-key cryptography.
Most other programming languages (Ruby, Erlang, Node.js) still only offer OpenSSL, which invites developers to (mis)use RSA, encrypt using AES in ECB mode, and never authenticate their ciphertexts. Furthermore, many of these languages still use OpenSSL's userspace PRNG and don't expose a sane API for accessing the operating system's CSPRNG. (PHP solved this in 7.0.)
No matter how you feel about PHP, the reality is that PHP is the first programming language to commit to modern cryptography in its standard library, coming in version 7.2.0.
If you're a passionate language evangelist, the best thing to do now is to strive for second-to-market. I'm excited to see everyone abandon the fossils of RSA and foot-bullety ECDSA.
Trending on dev.to
Developer whimsy: Llamas in Pajamas
What is Management?
I think I will leave my job, give me a advice.
Programming is ...
What I like about dev.to... and what I dont (DEP 0)
I am a developer. How can I make money?
Which browsers should I try to support when creating a portfolio?
Workflow Wednesday - Spectacle
69
22

I quite like this, but couldn't they come up with a better function name than
sodium_crypto_box_keypair_from_secretkey_and_publickey()?I agree, this function name is so short, can be longer. :P
does it REALLY need to be that long?
I mean sodium_dh_create() would work too.
The long function name was probably chosen to increase security by obscurity (joking) :-)
Wow, this is probably the longest function name ever.
Thank you so much, I wasted roughly 12 hours trying to get something to work where python signed a message that a PHP script on a different machine could properly and safely verify. I was messing around with phpecc (github project) and other stuff and was getting rather frustrated.
Saw the post on libsodium in php 7.2, built the PECL module for PHP 7.1 and the python library pysodium - and within an hour had something that actually worked with very little code.
Again, thank you so much. With the convoluted stuff I was trying, I was really afraid my app would end up being an example in the wild where cryptography went bad because the developer messed up.
8th has had built-in crypto, using AES+GCM by default, since its inception.
hope it's also simple to use. having to work with objects and bla bla bla isnt needed imo.
the most simple would be just
put in message and key and it will automatically do IV, and all the other needed stuff for AESGCM.
It does do all that pretty much. It's not an OOP language.
For example:
"some plaintext" "mypassword" "salt" 100 cr:genkey
cr:>encrypt cr:encrypt>
After that, you'll have an AES+GCM+256 encrypted buffer. You could also have skipped all the "mypassword"... genkey by using cr:randkey ... but then you would need to store that key somewhere.
If you choose to use CTR mode, you need to supply an IV, but the default is GCM.
Oh, and the reason there are two encrypt words there, is that one starts encryption and the other ends it. You can keep adding stuff to be encrypted, so for example you could encrypt a very large data stream on the fly if you wanted.
Unfortunately:
Hey there, we see you aren't signed in. (Yes you, the reader. This is a fake comment.)
Please consider creating an account on dev.to. It literally takes a few seconds and we'd appreciate the support so much. ❤️
Plus, no fake comments when you're signed in. 🙃
How about C#? That hasn't got modern cryptography built-in?
No, it doesn't.
Please, everyone, look at the documentation for the language you're writing in and compare it to the established criteria of this post before you ask about it.
C# gives you NIST curves, not modern ECC (RFC 7748). C# doesn't give you a simple misuse-resistant AEAD interface like crypto_secretbox() or crypto_box() as part of the standard API. Therefore, it's not modern cryptography.
You can get that if you install libsodium-net by Adam Caudill. But that's not part of the language, that's a community-provided addon.
Damn, that is cool! Shame I don’t know what any of that meant though…
The what does this mean for me part was a sweet relief, everything before it was :eyes_rolling:
Can you make a tutorial with real exemple on php 7.2 ?, would be great !