Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/32' into develop
Browse files Browse the repository at this point in the history
Close #32
  • Loading branch information
weierophinney committed Aug 11, 2016
2 parents cb58421 + 31c40e1 commit 874a8a1
Show file tree
Hide file tree
Showing 9 changed files with 471 additions and 28 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ All notable changes to this project will be documented in this file, in reverse

### Added

- Nothing.
- [#32](https://github.com/zendframework/zend-crypt/pull/32) adds a new Hybrid
encryption utility, to allow OpenPGP-like encryption/decryption of messages
using OpenSSL. See the documentation for details.

### Deprecated

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
[![Coverage Status](https://coveralls.io/repos/zendframework/zend-crypt/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-crypt?branch=master)

`Zend\Crypt` provides support of some cryptographic tools.
The available features are:
Some of the available features are:

- encrypt-then-authenticate using symmetric ciphers (the authentication step
is provided using HMAC);
- encrypt/decrypt using symmetric and public key algorithm (e.g. RSA algorithm);
- encrypt/decrypt using hybrid mode (OpenPGP like);
- generate digital sign using public key algorithm (e.g. RSA algorithm);
- key exchange using the Diffie-Hellman method;
- key derivation function (e.g. using PBKDF2 algorithm);
Expand Down
51 changes: 26 additions & 25 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

120 changes: 120 additions & 0 deletions doc/book/hybrid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Encrypt and decrypt using hybrid cryptosystem - Since 3.1.0

Hybrid is an encryption mode that uses symmetric and public key ciphers together.
The approach takes advantage of public key cryptography for sharing keys and
symmetric encryption speed for encrypting messages.

Hybrid mode allows you to encrypt a message for one or more receivers, and can
be used in multi-user scenarios where you wish to limit decryption to specific
users.

## How it works

Suppose we have two users: *Alice* and *Bob*. *Alice* wants to send a message to *Bob*
using a hybrid cryptosystem, she needs to:

- Obtain *Bob*'s public key;
- Generates a random session key (one-time pad);
- Encrypts message using a symmetric cipher with the previous session key;
- Encrypts session key using the *Bob*'s public key;
- Sends both the encrypted message and encrypted session key to *Bob*.

A schema of the encryption is reported in the image below:

![Encryption schema](images/zend.crypt.hybrid.png)

To decrypt the message, *Bob* needs to:

- Uses his private key to decrypt the session key;
- Uses this session key to decrypt the message.

## Example of usage

In order to use the `Zend\Crypt\Hybrid` component, you need to have a keyring of
public and private keys. To encrypt a message, use the following code:

```php
use Zend\Crypt\Hybrid;
use Zend\Crypt\PublicKey\RsaOptions;

// Generate public and private key
$rsaOptions = new RsaOptions([
'pass_phrase' => 'test'
]);
$rsaOptions->generateKeys([
'private_key_bits' => 4096
]);
$publicKey = $rsaOptions->getPublicKey();
$privateKey = $rsaOptions->getPrivateKey();

$hybrid = new Hybrid();
$ciphertext = $hybrid->encrypt('message', $publicKey);
$plaintext = $hybrid->decrypt($ciphertext, $privateKey);

printf($plaintext === 'message' ? "Success\n" : "Error\n");
```

We generated the keys using the [Zend\Crypt\PublicKey\RsaOptions](public-key.md)
component. You can also use a [PEM](https://en.wikipedia.org/wiki/Privacy-enhanced_Electronic_Mail)
string for the keys. If you use a string for the private key, you need to pass
the pass phrase to use when decrypting, if present, like in the following example:

```php
use Zend\Crypt\Hybrid;
use Zend\Crypt\PublicKey\RsaOptions;

// Generate public and private key
$rsaOptions = new RsaOptions([
'pass_phrase' => 'test'
]);
$rsaOptions->generateKeys([
'private_key_bits' => 4096
]);
// Strings in PEM format
$publicKey = $rsaOptions->getPublicKey()->toString();
$privateKey = $rsaOptions->getPrivateKey()->toString();

$hybrid = new Hybrid();
$ciphertext = $hybrid->encrypt('message', $publicKey);
$plaintext = $hybrid->decrypt($ciphertext, $privateKey, 'test'); // pass-phrase

printf($plaintext === 'message' ? "Success\n" : "Error\n");
```

The `Hybrid` component uses `Zend\Crypt\BlockCipher` for the symmetric
cipher and `Zend\Crypt\Rsa` for the public-key cipher.

## Encrypt with multiple keys

The `Zend\Crypt\Hybrid` component can be used to encrypt a message for multiple
users, using a keyring of identifiers and public keys. This keyring can be
specified using an array of `[ 'id' => 'publickey' ]`, where `publickey` can be
a string (PEM) or an instance of `Zend\Crypt\PublicKey\Rsa\PublicKey`. The `id`
can be any string, for example, a receipient email address.

The following details encryption using a keyring with 4 keys:

```php
use Zend\Crypt\Hybrid;
use Zend\Crypt\PublicKey\RsaOptions;

$publicKeys = [];
$privateKeys = [];
for ($id = 0; $id < 4; $id++) {
$rsaOptions = new RsaOptions([
'pass_phrase' => "test-$id"
]);
$rsaOptions->generateKeys([
'private_key_bits' => 4096
]);
$publicKeys[$id] = $rsaOptions->getPublicKey();
$privateKeys[$id] = $rsaOptions->getPrivateKey();
}

$hybrid = new Hybrid();
$encrypted = $hybrid->encrypt('message', $publicKeys);
for ($id = 0; $id < 4; $id++) {
$plaintext = $hybrid->decrypt($encrypted, $privateKeys[$id], null, $id);
printf($plaintext === 'message' ? "Success on %d\n" : "Error on %d\n", $id);
}
```
Binary file added doc/book/images/zend.crypt.hybrid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion doc/book/public-key.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ use Zend\Crypt\PublicKey\RsaOptions;

$rsaOptions = new RsaOptions([
'pass_phrase' => 'test'
[);
]);

$rsaOptions->generateKeys([
'private_key_bits' => 2048,
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pages:
- Reference:
- { 'Block Ciphers': block-cipher.md }
- { 'Encrypting Files': files.md }
- { 'Hybrid Cryptosystem': hybrid.md }
- { 'Key Derivation': key-derivation.md }
- { Passwords: password.md }
- { 'Public Key Cryptography': public-key.md }
Expand Down
Loading

0 comments on commit 874a8a1

Please sign in to comment.