This is an old revision of the document!
PHP RFC: Simple Cryptography Library
- Version: 0.1
- Date: 2016-01-09
- Author: Scott Arciszewski, security@paragonie.com
- Status: Draft
- First Published at: https://wiki.php.net/rfc/php71-crypto
Introduction
Cryptography is hard to get right, even for experts. Building atop the victories against insecure design that the password hashing API have brought us, I would seek to provide a simple, secure-by-default cryptography interface that puts as little burden on the user (PHP developers) as possible, that works with multiple cryptography backends.
Proposal
My proposal is to create a series of new classes (preferably in its own namespace, e.g. \Php\Crypto or simply \Cryptography):
Asymmetric\Crypto
Asymmetric\EncryptionSecretKey
Asymmetric\EncryptionPublicKey
Asymmetric\SignatureSecretKey
Asymmetric\SignaturePublicKey
Symmetric\AuthenticationKey
Symmetric\Crypto
Symmetric\EncryptionKey
Key
(base type that all *Key classes inherit from)KeyFactory
(abstract class, static methods)KeyPair
Users would primarily be interested in the Crypto
classes, and the methods of the KeyFactory
class. For example:
$keypair = \Php\Crypto\KeyFactory::generateEncryptionKeyPair('openssl'); var_dump($keypair); // An instance of \Php\Crypto\KeyPair $secret = $keypair->getSecretKey(); // \Php\Crypto\Asymmetric\EncryptionSecretKey $public = $keypair->getPublicKey(); // \Php\Crypto\Asymmetric\EncryptionPublicKey $fips = new \Php\Crypto\Asymmetric\Crypto([ 'driver' => 'openssl', 'cipher' => 'aes-256', 'hash' => 'sha384' ]); $ciphertext = $fips->seal( 'This is a text message', $public ); $plaintext = $fips->unseal( $ciphertext, $secret ); var_dump($plaintext === 'This is a text message'); // bool(true)
The Asymmetric\Crypto
interface would look like this:
* ''encrypt( string, EncryptionSecretKey, EncryptionPublicKey )'' * ''decrypt( string, EncryptionSecretKey, EncryptionPublicKey )'' * ''seal( string, EncryptionPublicKey )'' * ''unseal( string, EncryptionSecretKey )'' * ''sign( string, SignatureSecretKey )'' * ''verify( string, SignaturePublicKey, string )''
The Symmetric\Crypto
interface would look like this:
auth( string, AuthenticationKey )
verify( string, AuthenticationKey )
encrypt( string, EncryptionKey )
decrypt( string, EncryptionKey )
Proposed PHP Version(s)
This should be considered for inclusion in PHP 7.1
RFC Impact
To Existing Extensions
Unaffected PHP Functionality
Future Scope
Proposed Voting Choices
This is a new feature; would a 50%+1 majority be acceptable?
Patches and Tests
A prototype is available here, which fleshed out a lot of the ideas: https://github.com/paragonie/pco_prototype