Add defuse/php-encryption 2.0 to Composer dependencies

This commit is contained in:
Hypolite Petovan 2017-11-09 02:13:02 -05:00
parent ede20ac95a
commit 3b2cd85483
61 changed files with 6289 additions and 1 deletions

View file

@ -16,6 +16,7 @@
"ezyang/htmlpurifier": "~4.7.0",
"mobiledetect/mobiledetectlib": "2.8.*",
"league/html-to-markdown": "~4.4.1",
"defuse/php-encryption": "2.*",
"pear/Text_LanguageDetect": "1.*",
"pear-pear.php.net/Text_Highlighter": "*"
},

113
composer.lock generated
View file

@ -4,8 +4,71 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "a87f82da9a0256ca85c839e83a5c26f0",
"content-hash": "ce088458d9f01920ccee128082ef924a",
"packages": [
{
"name": "defuse/php-encryption",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/defuse/php-encryption.git",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"paragonie/random_compat": "~2.0",
"php": ">=5.4.0"
},
"require-dev": {
"nikic/php-parser": "^2.0|^3.0",
"phpunit/phpunit": "^4|^5"
},
"bin": [
"bin/generate-defuse-key"
],
"type": "library",
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "Secure PHP Encryption Library",
"keywords": [
"aes",
"authenticated encryption",
"cipher",
"crypto",
"cryptography",
"encrypt",
"encryption",
"openssl",
"security",
"symmetric key cryptography"
],
"time": "2017-05-18T21:28:48+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.7.0",
@ -166,6 +229,54 @@
],
"time": "2017-08-29T18:23:54+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.11",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2017-09-27T21:40:39+00:00"
},
{
"name": "pear-pear.php.net/Archive_Tar",
"version": "1.4.3",

17
vendor/bin/generate-defuse-key vendored Normal file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env sh
dir=$(d=${0%[/\\]*}; cd "$d"; cd "../defuse/php-encryption/bin" && pwd)
# See if we are running in Cygwin by checking for cygpath program
if command -v 'cygpath' >/dev/null 2>&1; then
# Cygwin paths start with /cygdrive/ which will break windows PHP,
# so we need to translate the dir path to windows format. However
# we could be using cygwin PHP which does not require this, so we
# test if the path to PHP starts with /cygdrive/ rather than /usr/bin
if [[ $(which php) == /cygdrive/* ]]; then
dir=$(cygpath -m "$dir");
fi
fi
dir=$(echo $dir | sed 's/ /\ /g')
"${dir}/generate-defuse-key" "$@"

4
vendor/bin/generate-defuse-key.bat vendored Normal file
View file

@ -0,0 +1,4 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/../defuse/php-encryption/bin/generate-defuse-key
php "%BIN_TARGET%" %*

View file

@ -8,13 +8,32 @@ $baseDir = dirname($vendorDir);
return array(
'Archive_Tar' => $vendorDir . '/pear-pear.php.net/Archive_Tar/Archive/Tar.php',
'Console_Getopt' => $vendorDir . '/pear-pear.php.net/Console_Getopt/Console/Getopt.php',
'Defuse\\Crypto\\Core' => $vendorDir . '/defuse/php-encryption/src/Core.php',
'Defuse\\Crypto\\Crypto' => $vendorDir . '/defuse/php-encryption/src/Crypto.php',
'Defuse\\Crypto\\DerivedKeys' => $vendorDir . '/defuse/php-encryption/src/DerivedKeys.php',
'Defuse\\Crypto\\Encoding' => $vendorDir . '/defuse/php-encryption/src/Encoding.php',
'Defuse\\Crypto\\Exception\\BadFormatException' => $vendorDir . '/defuse/php-encryption/src/Exception/BadFormatException.php',
'Defuse\\Crypto\\Exception\\CryptoException' => $vendorDir . '/defuse/php-encryption/src/Exception/CryptoException.php',
'Defuse\\Crypto\\Exception\\EnvironmentIsBrokenException' => $vendorDir . '/defuse/php-encryption/src/Exception/EnvironmentIsBrokenException.php',
'Defuse\\Crypto\\Exception\\IOException' => $vendorDir . '/defuse/php-encryption/src/Exception/IOException.php',
'Defuse\\Crypto\\Exception\\WrongKeyOrModifiedCiphertextException' => $vendorDir . '/defuse/php-encryption/src/Exception/WrongKeyOrModifiedCiphertextException.php',
'Defuse\\Crypto\\File' => $vendorDir . '/defuse/php-encryption/src/File.php',
'Defuse\\Crypto\\Key' => $vendorDir . '/defuse/php-encryption/src/Key.php',
'Defuse\\Crypto\\KeyOrPassword' => $vendorDir . '/defuse/php-encryption/src/KeyOrPassword.php',
'Defuse\\Crypto\\KeyProtectedByPassword' => $vendorDir . '/defuse/php-encryption/src/KeyProtectedByPassword.php',
'Defuse\\Crypto\\RuntimeTests' => $vendorDir . '/defuse/php-encryption/src/RuntimeTests.php',
'Detection\\MobileDetect' => $vendorDir . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php',
'Friendica\\App' => $baseDir . '/src/App.php',
'Friendica\\Core\\Config' => $baseDir . '/src/Core/Config.php',
'Friendica\\Core\\NotificationsManager' => $baseDir . '/src/Core/NotificationsManager.php',
'Friendica\\Core\\PConfig' => $baseDir . '/src/Core/PConfig.php',
'Friendica\\Core\\System' => $baseDir . '/src/Core/System.php',
'Friendica\\Core\\Worker' => $baseDir . '/src/Core/Worker.php',
'Friendica\\Database\\DBM' => $baseDir . '/src/Database/DBM.php',
'Friendica\\Network\\Probe' => $baseDir . '/src/Network/Probe.php',
'Friendica\\ParseUrl' => $baseDir . '/src/ParseUrl.php',
'Friendica\\Protocol\\DFRN' => $baseDir . '/src/Protocol/DFRN.php',
'Friendica\\Protocol\\Diaspora' => $baseDir . '/src/Protocol/Diaspora.php',
'Friendica\\Util\\Lock' => $baseDir . '/src/Util/Lock.php',
'HTMLPurifier' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.php',
'HTMLPurifier_Arborize' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/Arborize.php',

View file

@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
);

View file

@ -8,4 +8,5 @@ $baseDir = dirname($vendorDir);
return array(
'League\\HTMLToMarkdown\\' => array($vendorDir . '/league/html-to-markdown/src'),
'Friendica\\' => array($baseDir . '/src'),
'Defuse\\Crypto\\' => array($vendorDir . '/defuse/php-encryption/src'),
);

View file

@ -7,6 +7,7 @@ namespace Composer\Autoload;
class ComposerStaticInitFriendica
{
public static $files = array (
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
);
@ -19,6 +20,10 @@ class ComposerStaticInitFriendica
array (
'Friendica\\' => 10,
),
'D' =>
array (
'Defuse\\Crypto\\' => 14,
),
);
public static $prefixDirsPsr4 = array (
@ -30,6 +35,10 @@ class ComposerStaticInitFriendica
array (
0 => __DIR__ . '/../..' . '/src',
),
'Defuse\\Crypto\\' =>
array (
0 => __DIR__ . '/..' . '/defuse/php-encryption/src',
),
);
public static $prefixesPsr0 = array (
@ -59,13 +68,32 @@ class ComposerStaticInitFriendica
public static $classMap = array (
'Archive_Tar' => __DIR__ . '/..' . '/pear-pear.php.net/Archive_Tar/Archive/Tar.php',
'Console_Getopt' => __DIR__ . '/..' . '/pear-pear.php.net/Console_Getopt/Console/Getopt.php',
'Defuse\\Crypto\\Core' => __DIR__ . '/..' . '/defuse/php-encryption/src/Core.php',
'Defuse\\Crypto\\Crypto' => __DIR__ . '/..' . '/defuse/php-encryption/src/Crypto.php',
'Defuse\\Crypto\\DerivedKeys' => __DIR__ . '/..' . '/defuse/php-encryption/src/DerivedKeys.php',
'Defuse\\Crypto\\Encoding' => __DIR__ . '/..' . '/defuse/php-encryption/src/Encoding.php',
'Defuse\\Crypto\\Exception\\BadFormatException' => __DIR__ . '/..' . '/defuse/php-encryption/src/Exception/BadFormatException.php',
'Defuse\\Crypto\\Exception\\CryptoException' => __DIR__ . '/..' . '/defuse/php-encryption/src/Exception/CryptoException.php',
'Defuse\\Crypto\\Exception\\EnvironmentIsBrokenException' => __DIR__ . '/..' . '/defuse/php-encryption/src/Exception/EnvironmentIsBrokenException.php',
'Defuse\\Crypto\\Exception\\IOException' => __DIR__ . '/..' . '/defuse/php-encryption/src/Exception/IOException.php',
'Defuse\\Crypto\\Exception\\WrongKeyOrModifiedCiphertextException' => __DIR__ . '/..' . '/defuse/php-encryption/src/Exception/WrongKeyOrModifiedCiphertextException.php',
'Defuse\\Crypto\\File' => __DIR__ . '/..' . '/defuse/php-encryption/src/File.php',
'Defuse\\Crypto\\Key' => __DIR__ . '/..' . '/defuse/php-encryption/src/Key.php',
'Defuse\\Crypto\\KeyOrPassword' => __DIR__ . '/..' . '/defuse/php-encryption/src/KeyOrPassword.php',
'Defuse\\Crypto\\KeyProtectedByPassword' => __DIR__ . '/..' . '/defuse/php-encryption/src/KeyProtectedByPassword.php',
'Defuse\\Crypto\\RuntimeTests' => __DIR__ . '/..' . '/defuse/php-encryption/src/RuntimeTests.php',
'Detection\\MobileDetect' => __DIR__ . '/..' . '/mobiledetect/mobiledetectlib/namespaced/Detection/MobileDetect.php',
'Friendica\\App' => __DIR__ . '/../..' . '/src/App.php',
'Friendica\\Core\\Config' => __DIR__ . '/../..' . '/src/Core/Config.php',
'Friendica\\Core\\NotificationsManager' => __DIR__ . '/../..' . '/src/Core/NotificationsManager.php',
'Friendica\\Core\\PConfig' => __DIR__ . '/../..' . '/src/Core/PConfig.php',
'Friendica\\Core\\System' => __DIR__ . '/../..' . '/src/Core/System.php',
'Friendica\\Core\\Worker' => __DIR__ . '/../..' . '/src/Core/Worker.php',
'Friendica\\Database\\DBM' => __DIR__ . '/../..' . '/src/Database/DBM.php',
'Friendica\\Network\\Probe' => __DIR__ . '/../..' . '/src/Network/Probe.php',
'Friendica\\ParseUrl' => __DIR__ . '/../..' . '/src/ParseUrl.php',
'Friendica\\Protocol\\DFRN' => __DIR__ . '/../..' . '/src/Protocol/DFRN.php',
'Friendica\\Protocol\\Diaspora' => __DIR__ . '/../..' . '/src/Protocol/Diaspora.php',
'Friendica\\Util\\Lock' => __DIR__ . '/../..' . '/src/Util/Lock.php',
'HTMLPurifier' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.php',
'HTMLPurifier_Arborize' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier/Arborize.php',

View file

@ -442,5 +442,120 @@
],
"description": "Identify human languages from text samples",
"homepage": "http://pear.php.net/package/Text_LanguageDetect"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.11",
"version_normalized": "2.0.11.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"time": "2017-09-27T21:40:39+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
]
},
{
"name": "defuse/php-encryption",
"version": "v2.1.0",
"version_normalized": "2.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/defuse/php-encryption.git",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/defuse/php-encryption/zipball/5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"reference": "5176f5abb38d3ea8a6e3ac6cd3bbb54d8185a689",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"paragonie/random_compat": "~2.0",
"php": ">=5.4.0"
},
"require-dev": {
"nikic/php-parser": "^2.0|^3.0",
"phpunit/phpunit": "^4|^5"
},
"time": "2017-05-18T21:28:48+00:00",
"bin": [
"bin/generate-defuse-key"
],
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "Secure PHP Encryption Library",
"keywords": [
"aes",
"authenticated encryption",
"cipher",
"crypto",
"cryptography",
"encrypt",
"encryption",
"openssl",
"security",
"symmetric key cryptography"
]
}
]

11
vendor/defuse/php-encryption/.gitignore vendored Normal file
View file

@ -0,0 +1,11 @@
*~
/test/unit/File/big-generated-file
/composer.lock
/vendor
defuse-crypto.phar
defuse-crypto.phar.sig
composer.phar
box.phar
phpunit.phar
phpunit.phar.asc
test/unit/File/tmp

60
vendor/defuse/php-encryption/.php_cs vendored Normal file
View file

@ -0,0 +1,60 @@
<?php
$config = Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers([
'blankline_after_open_tag',
'empty_return',
'extra_empty_lines',
'function_typehint_space',
'join_function',
'method_argument_default_value',
'multiline_array_trailing_comma',
'no_blank_lines_after_class_opening',
'no_empty_lines_after_phpdocs',
'phpdoc_indent',
'phpdoc_no_access',
'phpdoc_no_empty_return',
'phpdoc_no_package',
'phpdoc_params',
'phpdoc_scalar',
'phpdoc_separation',
'phpdoc_trim',
'phpdoc_type_to_var',
'phpdoc_types',
'phpdoc_var_without_name',
'remove_leading_slash_use',
'remove_lines_between_uses',
'short_bool_cast',
'single_quote',
'spaces_after_semicolon',
'spaces_before_semicolon',
'spaces_cast',
'standardize_not_equal',
'ternary_spaces',
'trim_array_spaces',
'unneeded_control_parentheses',
'unused_use',
'whitespacy_lines',
'align_double_arrow',
'concat_with_spaces',
'logical_not_operators_with_successor_space',
'multiline_spaces_before_semicolon',
'newline_after_open_tag',
'ordered_use',
'php_unit_construct',
'phpdoc_order',
'short_array_syntax',
]);
if (null === $input->getArgument('path')) {
$config
->finder(
Symfony\CS\Finder\DefaultFinder::create()
->in('src')
->in('test')
->exclude('vendor')
);
}
return $config;

21
vendor/defuse/php-encryption/LICENSE vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Taylor Hornby <https://defuse.ca> and Paragon Initiative
Enterprises <https://paragonie.com>.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

88
vendor/defuse/php-encryption/README.md vendored Normal file
View file

@ -0,0 +1,88 @@
php-encryption
===============
[![Build Status](https://travis-ci.org/defuse/php-encryption.svg?branch=master)](https://travis-ci.org/defuse/php-encryption)
This is a library for encrypting data with a key or password in PHP. **It
requires PHP 5.4 or newer.** The current version is v2.0.0, which is expected to
remain stable and supported by its authors with security and bugfixes until at
least January 1st, 2019.
The library is a joint effort between [Taylor Hornby](https://defuse.ca/) and
[Scott Arciszewski](https://paragonie.com/blog/author/scott-arcizewski) as well
as numerous open-source contributors.
What separates this library from other PHP encryption libraries is, firstly,
that it is secure. The authors used to encounter insecure PHP encryption code on
a daily basis, so they created this library to bring more security to the
ecosystem. Secondly, this library is "difficult to misuse." Like
[libsodium](https://github.com/jedisct1/libsodium), its API is designed to be
easy to use in a secure way and hard to use in an insecure way.
Dependencies
------------
This library requres no special dependencies except for PHP 5.4 or newer with
the OpenSSL extensions enabled (this is the default). It uses
[random\_compat](https://github.com/paragonie/random_compat), which is bundled
in with this library so that your users will not need to follow any special
installation steps.
Getting Started
----------------
Start with the [**Tutorial**](docs/Tutorial.md). You can find instructions for
obtaining this library's code securely in the [Installing and
Verifying](docs/InstallingAndVerifying.md) documentation.
After you've read the tutorial and got the code, refer to the formal
documentation for each of the classes this library provides:
- [Crypto](docs/classes/Crypto.md)
- [File](docs/classes/File.md)
- [Key](docs/classes/Key.md)
- [KeyProtectedByPassword](docs/classes/KeyProtectedByPassword.md)
If you encounter difficulties, see the [FAQ](docs/FAQ.md) answers. The fixes to
the most commonly-reported problems are explained there.
If you're a cryptographer and want to understand the nitty-gritty details of how
this library works, look at the [Cryptography Details](docs/CryptoDetails.md)
documentation.
If you're interested in contributing to this library, see the [Internal
Developer Documentation](docs/InternalDeveloperDocs.md).
Examples
---------
If the documentation is not enough for you to understand how to use this
library, then you can look at an example project that uses this library:
- [encutil](https://github.com/defuse/encutil)
- [fileencrypt](https://github.com/tsusanka/fileencrypt)
Security Audit Status
---------------------
This code has not been subjected to a formal, paid, security audit. However, it
has received lots of review from members of the PHP security community, and the
authors are experienced with cryptography. In all likelihood, you are safer
using this library than almost any other encryption library for PHP.
If you use this library as a part of your business and would like to help fund
a formal audit, please [contact Taylor Hornby](https://defuse.ca/contact.htm).
Public Keys
------------
The GnuPG public key used to sign releases is available in
[dist/signingkey.asc](https://github.com/defuse/php-encryption/raw/master/dist/signingkey.asc). Its fingerprint is:
```
2FA6 1D8D 99B9 2658 6BAC 3D53 385E E055 A129 1538
```
You can verify it against the Taylor Hornby's [contact
page](https://defuse.ca/contact.htm) and
[twitter](https://twitter.com/DefuseSec/status/723741424253059074).

View file

@ -0,0 +1,14 @@
#!/usr/bin/env php
<?php
use Defuse\Crypto\Key;
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
if (file_exists($file)) {
require $file;
break;
}
}
$key = Key::createNewRandomKey();
echo $key->saveToAsciiSafeString(), "\n";

View file

@ -0,0 +1,35 @@
{
"name": "defuse/php-encryption",
"description": "Secure PHP Encryption Library",
"license": "MIT",
"keywords": ["security", "encryption", "AES", "openssl", "cipher", "cryptography", "symmetric key cryptography", "crypto", "encrypt", "authenticated encryption"],
"authors": [
{
"name": "Taylor Hornby",
"email": "taylor@defuse.ca",
"homepage": "https://defuse.ca/"
},
{
"name": "Scott Arciszewski",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"autoload": {
"psr-4": {
"Defuse\\Crypto\\": "src"
}
},
"require": {
"paragonie/random_compat": "~2.0",
"ext-openssl": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4|^5",
"nikic/php-parser": "^2.0|^3.0"
},
"bin": [
"bin/generate-defuse-key"
]
}

View file

@ -0,0 +1,37 @@
# This builds defuse-crypto.phar. To run this Makefile, `box` and `composer`
# must be installed and in your $PATH. Run it from inside the dist/ directory.
box := $(shell which box)
composer := "composer"
.PHONY: all
all: build-phar
.PHONY: sign-phar
sign-phar:
gpg -u 7B4B2D98 --armor --output defuse-crypto.phar.sig --detach-sig defuse-crypto.phar
# ensure we run in clean tree. export git tree and run there.
.PHONY: build-phar
build-phar:
@echo "Creating .phar from revision $(shell git rev-parse HEAD)."
rm -rf worktree
install -d worktree
(cd $(CURDIR)/..; git archive HEAD) | tar -x -C worktree
$(MAKE) -f $(CURDIR)/Makefile -C worktree defuse-crypto.phar
mv worktree/*.phar .
rm -rf worktree
.PHONY: clean
clean:
rm -vf defuse-crypto.phar defuse-crypto.phar.sig
# Inside workdir/:
defuse-crypto.phar: dist/box.json composer.lock
cp dist/box.json .
php -d phar.readonly=0 $(box) build -c box.json -v
composer.lock:
$(composer) install --no-dev

View file

@ -0,0 +1,25 @@
{
"chmod": "0755",
"finder": [
{
"in": "src",
"name": "*.php"
},
{
"in": "vendor/composer",
"name": "*.php"
},
{
"in": "vendor/paragonie",
"name": "*.php",
"exclude": "other"
}
],
"compactors": [
"Herrera\\Box\\Compactor\\Php"
],
"main": "vendor/autoload.php",
"output": "defuse-crypto.phar",
"shebang": false,
"stub": true
}

View file

@ -0,0 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
mQINBFarvO4BEACdQBaLt6SUBx1cB5liUu1qo+YwVLh9bxTregQtmEREMdTVqXYt
e5b79uL4pQp2GlKHcEyRURS+6rIIruM0oh9ZYGTJYPAkCDzJxaU2awZeFbfBvpCm
iF66/O4ZJI4mlT8dFKmxBJxDhfeOR2UmmhDiEsJK9FxBKUzvo/dWrX2pBzf8Y122
iIaVraSo+tymaf7vriaIf/NnSKhDw8dtQYGM4NMrxxsPTfbCF8XiboDgTkoD2A+6
NpOJYxA4Veedsf2TP9YLhljH4m5yYlfjjqBzbBCPWuE6Hhy5Xze9mncgDr7LKenm
Ctf2NxW6y4O3RCI+9eLlBfFWB+KuGV87/b5daetX7NNLbjID8z2rqEa+d6wu5xA5
Ta2uiVkAOEovr3XnkayZ9zth+Za7w7Ai0ln0N/LVMkM+Gu4z/pJv6HjmTGDM2wJb
fs+UOM0TFdg+N81Do67XT2M4o0MeHyUqsIiWpYa2Qf1PNmqTQNJnRk8uZZ9I96Nh
eCgNuCbhsQiYBMicox+xmuWAlGAfA06y0kCtmqGhiBGArdJlWvUqPqGiZ4Hln9z0
FJmXDOh0Q/FIPxcDg8mKRRbx+lOP389PLsPpj4b2B/4PEgfpCCOwuKpLotATZxC1
9JwFk0Y/cvUUkq4a+nAJBNtBbtRJkEesuuUnRq6XexmnE3uUucDcV0XCSwARAQAB
tCBUYXlsb3IgSG9ybmJ5IDx0YXlsb3JAZGVmdXNlLmNhPokCPQQTAQgAJwUCVqu8
7gIbAwUJB4TOAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRA4XuBVoSkVOJbx
EACG0F9blPMAsK05EWyNnnS4mw25zPfbaqqEvYbquAeM0nBpRDm7sRn2MNR0AL4g
7XrtxE/4qYkdEl6f2wFCQeRhZgxE3w22llredzLme11Hic8hn4i7ysdIw0r9dMMR
kjgR5UcWpv8iU847czyK09PkKW2EaLRbX2qbA7rNU5qCFKeD4Sy4bBTteISeVsHo
Vr9o1/bRrMhgZ++ts8hYf0LmujIf5cxp+qcdKwCXSnS/gmmXaKRMCPv/Wdlq9bt6
LX9jZB9lXBdGxcBJeFOsTG+QRDiVjg3d6i3o3TAKV87ALBI4v2ADEYtN8lviHo3/
SovVKv6zrUsZHxhoGiLTiksNrYsKMmiMxdJCoOazmtUPnZ4UOtT8NdqMPoKvdoRz
f4rhZ+f5jSVD9OuX2PDmfyq21Rdiym7Vcgr+uTIFJ3ShRHjWb/ytCwoB2FeGY6+G
AKY58bTQvUIqEJvSov/+TAqZ4BfOuSdTLcHglV1OdUu2SFZvU2gmyVp0l5elGv5t
FyUlBJUkQT9MtvsdLOR7vQi8QapV+9LWpqwvaj9hyEJz848DQ2sdYTphUytFHv7H
k58DAtVhTrVjHyeefjiYtMl6vSAgTjy5LWAUpo5TfhdGrAi0Tdd/GD7amHoWoDy8
EKXKq2xPLo3JOdkWYQUi5NErzEskfsSzpCOgyDJmGetWK7kCDQRWq7zuARAAu7/i
cm8cjgLhHEX/bgfwOT2hLOLSjjve0O8YFSuJO9XqIHXqmfVOrqWtfG0Mh4bwlfqc
MAvBfF5NSSPfAE4ftBAQ1e5jEv8hJeqICpq3IHTFX4etBs49NfNkyveQl/amVTu1
+/O5J4CuIcsEf3y0Xuu38n7EB3SfMQCWLcOR1NyZoX3bI+CGRpOVVoFse3ljSWL4
LhLVl0WiEMXULsussEoN+c6x9KCyAi/jFOrxrTrFC//sZesKj6KucoqKGfwMWrrv
IeRT9Ga8Wn5MJnQu0aWg+zVVYqTedXZLNLODgQIInFnXO0seBXy15yDok1y5bkx2
sinKg4+mueYaGUpoUti0hM3J3yaC34i6Cwa8MQoLNw1JIS/oNtKjpMxyV10w8aoc
PHRK3n7UYp10mJHx7aM+lldSKvVS1NTQmI4vloNLwMp324H5ANDFAlRUz7mysVnu
DEEvigPSPxs5ZYENu/i7pCQC5qHfhrlBrQwTjhegr0pQPcumy2fO5SGC9l/5B7ev
bqQSZmDeWWoTvh2w2wl5/RWAsgZKx6rDtkCqYx7sSBY17uorrxP24LP4zhq7NxRV
nfdsLogbCFNVQ66u7qvq5zFccdFtg9h1HQWdS7wbnKSBGZoo5gl6js7GGtxfGbb0
oQ9kp6eciF4U92r6POhVgbRe4CfPo50nqgZBddkAEQEAAYkCJQQYAQgADwUCVqu8
7gIbDAUJB4TOAAAKCRA4XuBVoSkVOFJ8D/9J8IJ4XWUU3FYIaHJ3XeSoxDmTi7d5
WmNdf1lmwz82MQjG4uw17oCbvQzmj4/a/CM1Ly4v0WwBhUf9aiNErD0ByHASFnuc
tlQBLVJdk0vRyD0fZakGg64qCA76hiySjMhlGHkQFyP2mDORc2GNu/OqFGm79pXT
ZUplXxd431E603/agM5xJrweutMMpP1nBFTSEMJvbMNzDVN8I1A1CH4zVmAVxOUk
sQ5L5rXW+KeXWyiMF24+l2CMnkQ2CxfHpkcpfPJs1Cbt+TIBSSofIqK8QJXrb/2f
Zpl/ftqW7Xe86rJFrB/Y/77LDWx10rqWEvfCqrBxrMj7ONAQfbKQF/IjAwDN17Wf
1K74rqKnRu+KHCyNM89s1iDbQC9kzZfzYt4AEOvAH/ZQDMZffzPSbnfkBerExFpa
93XMuiR66jiBsf9IXIQeydpJD4Ogl2sSUSxFEJxJ/bBSxPxC5w7/BVMA7Am1y8Zo
3hrpqnX2PBzxG7L0FZ6fYkfR3p8JS7vI6nByBf2IDv8W32wn43olPf+u6uobHLvt
ttapOjwPAhPDalRuxs9U6WSg06QJkT/0F8TFUPWpsFmKTl+G4Ty7PHWsjeeNHJCL
7/5RQboFY3k8Jy3/sIofABO6Un9LJivDuu9PxqA0IgvaS6Mja8JdCCk9Nyk4vHB7
IEgAL/CYqrk38w==
=lmD7
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,64 @@
Cryptography Details
=====================
Here is a high-level description of how this library works. Any discrepancy
between this documentation and the actual implementation will be considered
a security bug.
Let's start with the following definitions:
- HKDF-SHA256(*k*, *n*, *info*, *s*) is the key derivation function specified in
RFC 5869 (using the SHA256 hash function). The parameters are:
- *k*: The initial keying material.
- *n*: The number of output bytes.
- *info*: The info string.
- *s*: The salt.
- AES-256-CTR(*m*, *k*, *iv*) is AES-256 encryption in CTR mode. The parameters
are:
- *m*: An arbitrary-length (possibly zero-length) message.
- *k*: A 32-byte key.
- *iv*: A 16-byte initialization vector (nonce).
- PBKDF2-SHA256(*p*, *s*, *i*, *n*) is the password-based key derivation
function defined in RFC 2898 (using the SHA256 hash function). The parameters
are:
- *p*: The password string.
- *s*: The salt string.
- *i*: The iteration count.
- *n*: The output length in bytes.
- VERSION is the string `"\xDE\xF5\x02\x00"`.
- AUTHINFO is the string `"DefusePHP|V2|KeyForAuthentication"`.
- ENCRINFO is the string `"DefusePHP|V2|KeyForEncryption"`.
To encrypt a message *m* using a 32-byte key *k*, the following steps are taken:
1. Generate a random 32-byte string *salt*.
2. Derive the 32-byte authentication key *akey* = HKDF-SHA256(*k*, 32, AUTHINFO, *salt*).
3. Derive the 32-byte encryption key *ekey* = HKDF-SHA256(*k*, 32, ENCRINFO, *salt*).
4. Generate a random 16-byte initialization vector *iv*.
5. Compute *c* = AES-256-CTR(*m*, *ekey*, *iv*).
6. Combine *ctxt* = VERSION || *salt* || *iv* || *c*.
7. Compute *h* = HMAC-SHA256(*ctxt*, *akey*).
8. Output *ctxt* || *h*.
Decryption is roughly the reverse process (see the code for details, since the
security of the decryption routine is highly implementation-dependent).
For encryption using a password *p*, steps 1-3 above are replaced by:
1. Generate a random 32-byte string *salt*.
2. Compute *k* = PBKDF2-SHA256(SHA256(*p*), *salt*, 100000, 32).
3. Derive the 32-byte authentication key *akey* = HKDF-SHA256(*k*, 32, AUTHINFO, *salt*)
4. Derive the 32-byte encryption key *ekey* = HKDF-SHA256(*k*, 32, ENCRINFO, *salt*)
The remainder of the process is the same. Notice the reuse of the same *salt*
for PBKDF2-SHA256 and HKDF-SHA256. The prehashing of the password in step 2 is
done to prevent a [DoS attack using long
passwords](https://github.com/defuse/php-encryption/issues/230).
For `KeyProtectedByPassword`, the serialized key is encrypted according to the
password encryption defined above. However, the actual password used for
encryption is the SHA256 hash of the password the user provided. This is done in
order to provide domain separation between the message encryption in the user's
application and the internal key encryption done by this library. It fixes
a [key replacement chosen-protocol
attack](https://github.com/defuse/php-encryption/issues/240).

View file

@ -0,0 +1,39 @@
Frequently Asked Questions
===========================
How do I use this library to encrypt passwords?
------------------------------------------------
Passwords should not be encrypted, they should be hashed with a *slow* password
hashing function that's designed to slow down password guessing attacks. See
[How to Safely Store Your Users' Passwords in
2016](https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016).
How do I give it the same key every time instead of a new random key?
----------------------------------------------------------------------
A `Key` object can be saved to a string by calling its `saveToAsciiSafeString()`
method. You will have to save that string somewhere safe, and then load it back
into a `Key` object using `Key`'s `loadFromAsciiSafeString` static method.
Where you store the string depends on your application. For example if you are
using `KeyProtectedByPassword` to encrypt files with a user's login password,
then you should not store the `Key` at all. If you are protecting sensitive data
on a server that may be compromised, then you should store it in a hardware
security module. When in doubt, consult a security expert.
Why is an EnvironmentIsBrokenException getting thrown?
-------------------------------------------------------
Either you've encountered a bug in this library, or your system doesn't support
the use of this library. For example, if your system does not have a secure
random number generator, this library will refuse to run, by throwing that
exception, instead of falling back to an insecure random number generator.
Why am I getting a BadFormatException when loading a Key from a string?
------------------------------------------------------------------------
If you're getting this exception, then the string you're giving to
`loadFromAsciiSafeString()` is *not* the same as the string you got from
`saveToAsciiSafeString()`. Perhaps your database column isn't wide enough and
it's truncating the string as you insert it?

View file

@ -0,0 +1,53 @@
Getting The Code
=================
There are two ways to use this library in your applications. You can either:
1. Use [Composer](https://getcomposer.org/), or
2. `require_once` a single `.phar` file in your application.
If you are not using either option (for example, because you're using Git submodules), you may need to write your own autoloader ([example](https://gist.github.com/paragonie-scott/949daee819bb7f19c50e5e103170b400)).
Option 1: Using Composer
-------------------------
Run this inside the directory of your composer-enabled project:
```sh
composer require defuse/php-encryption
```
Unfortunately, composer doesn't provide a way for you to verify that the code
you're getting was signed by this library's authors. If you want a more secure
option, use the `.phar` method described below.
Option 2: Including a PHAR
----------------------------
The `.phar` option lets you include this library into your project simply by
calling `require_once` on a single file. Download `defuse-crypto.phar` and
`defuse-crypto.phar.sig` from this project's
[releases](https://github.com/defuse/php-encryption/releases) page.
You should verify the integrity of the `.phar`. The `defuse-crypto.phar.sig`
contains the signature of `defuse-crypto.phar`. It is signed with Taylor
Hornby's PGP key. You can find Taylor's public key in `dist/signingkey.asc`. You
can verify the public key's fingerprint against the Taylor Hornby's [contact
page](https://defuse.ca/contact.htm) and
[twitter](https://twitter.com/DefuseSec/status/723741424253059074).
Once you have verified the signature, it is safe to use the `.phar`. Place it
somewhere in your file system, e.g. `/var/www/lib/defuse-crypto.phar`, and then
pass that path to `require_once`.
```php
<?php
require_once('/var/www/lib/defuse-crypto.phar');
// ... the Crypto, File, Key, and KeyProtectedByPassword classes are now
// available ...
// ...
```

View file

@ -0,0 +1,160 @@
Information for the Developers of php-encryption
=================================================
Status
-------
This library is currently frozen under a long-term support release. We do not
plan to add any new features. We will maintain the library by fixing any bugs
that are reported, or security vulnerabilities that are found.
Development Environment
------------------------
Development is done on Linux. To run the tests, you will need to have the
following tools installed:
- `php` (with OpenSSL enabled, if you're compiling from source).
- `gpg`
- `composer`
Running the Tests
------------------
First do `composer install` and then you can run the tests by running
`./test.sh`. This will download a PHPUnit PHAR, verify its cryptographic
signatures, and then use it to run the tests in `test/unit`.
Getting and Using Psalm
-----------------------
[Psalm](https://github.com/vimeo/psalm) is a static analysis suite for PHP projects.
We use Psalm to ensure type safety throughout our library.
To install Psalm, you just need to run one command:
composer require --dev "vimeo/psalm:dev-master"
To verify that your code changes are still strictly type-safe, run the following
command:
vendor/bin/psalm
Reporting Bugs
---------------
Please report bugs, even critical security vulnerabilities, by opening an issue
on GitHub. We recommend disclosing security vulnerabilities found in this
library *publicly* as soon as possible.
Philosophy
-----------
This library is developed around several core values:
- Rule #1: Security is prioritized over everything else.
> Whenever there is a conflict between security and some other property,
> security will be favored. For example, the library has runtime tests,
> which make it slower, but will hopefully stop it from encrypting stuff
> if the platform it's running on is broken.
- Rule #2: It should be difficult to misuse the library.
> We assume the developers using this library have no experience with
> cryptography. We only assume that they know that the "key" is something
> you need to encrypt and decrypt the messages, and that it must be kept
> secret. Whenever possible, the library should refuse to encrypt or decrypt
> messages when it is not being used correctly.
- Rule #3: The library aims only to be compatible with itself.
> Other PHP encryption libraries try to support every possible type of
> encryption, even the insecure ones (e.g. ECB mode). Because there are so
> many options, inexperienced developers must decide whether to use "CBC
> mode" or "ECB mode" when both are meaningless terms to them. This
> inevitably leads to vulnerabilities.
> This library will only support one secure mode. A developer using this
> library will call "encrypt" and "decrypt" methods without worrying about
> how they are implemented.
- Rule #4: The library should require no special installation.
> Some PHP encryption libraries, like libsodium-php, are not straightforward
> to install and cannot packaged with "just download and extract"
> applications. This library will always be just a handful of PHP files that
> you can copy to your source tree and require().
Publishing Releases
--------------------
To make a release, you will need to install [composer](https://getcomposer.org/)
and [box](https://github.com/box-project/box2) on your system. They will need to
be available in your `$PATH` so that running the commands `composer` and `box`
in your terminal run them, respectively. You will also need the private key for
signing (ID: 7B4B2D98) available.
Once you have those tools installed and the key available follow these steps:
**Remember to set the version number in `composer.json`!**
Make a fresh clone of the repository:
```
git clone <url>
```
Check out the branch you want to release:
```
git checkout <branchname>
```
Check that the version number in composer.json is correct:
```
cat composer.json
```
Run the tests:
```
composer install
./test.sh
```
Generate the `.phar`:
```
cd dist
make build-phar
```
Test the `.phar`:
```
cd ../
./test.sh dist/defuse-crypto.phar
```
Sign the `.phar`:
```
cd dist
make sign-phar
```
Tag the release:
```
git -c user.signingkey=7B4B2D98 tag -s "<TAG NAME>" -m "<TAG MESSAGE>"
```
`<TAG NAME>` should be in the format `v2.0.0` and `<TAG MESSAGE>` should look
like "Release of v2.0.0."
Push the tag to github, then use the
[releases](https://github.com/defuse/php-encryption/releases) page to draft
a new release for that tag. Upload the `.phar` and the `.phar.sig` file to be
included as part of that release.

View file

@ -0,0 +1,298 @@
Tutorial
=========
Hello! If you're reading this file, it's because you want to add encryption to
one of your PHP projects. My job, as the person writing this documentation, is
to help you make sure you're doing the right thing and then show you how to use
this library to do it. To help me help you, please read the documentation
*carefully* and *deliberately*.
A Word of Caution
------------------
Encryption is not magic dust you can sprinkle on a system to make it more
secure. The way encryption is integrated into a system's design needs to be
carefully thought out. Sometimes, encryption is the wrong thing to use. Other
times, encryption needs to be used in a very specific way in order for it to
work as intended. Even if you are sure of what you are doing, we strongly
recommend seeking advice from an expert.
The first step is to think about your application's threat model. Ask yourself
the following questions. Who will want to attack my application, and what will
they get out of it? Are they trying to steal some information? Trying to alter
or destroy some information? Or just trying to make the system go down so people
can't access it? Then ask yourself how encryption can help combat those threats.
If you're going to add encryption to your application, you should have a very
clear idea of exactly which kinds of attacks it's helping to secure your
application against. Once you have your threat model, think about what kinds of
attacks it *does not* cover, and whether or not you should improve your threat
model to include those attacks.
**This isn't for storing user login passwords:** The most common use of
cryptography in web applications is to protect the users' login passwords. If
you're trying to use this library to "encrypt" your users' passwords, you're in
the wrong place. Passwords shouldn't be *encrypted*, they should be *hashed*
with a slow computation-heavy function that makes password guessing attacks more
expensive. See [How to Safely Store Your Users' Passwords in
2016](https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016).
**This isn't for encrypting network communication:** Likewise, if you're trying
to encrypt messages sent between two parties over the Internet, you don't want
to be using this library. For that, set up a TLS connection between the two
points, or, if it's a chat app, use the [Signal
Protocol](https://whispersystems.org/blog/advanced-ratcheting/).
What this library provides is symmetric encryption for "data at rest." This
means it is not suitable for use in building protocols where "data is in motion"
(i.e. moving over a network) except in limited set of cases.
Getting the Code
-----------------
There are several different ways to obtain this library's code and to add it to
your project. Even if you've already cloned the code from GitHub, you should
take steps to verify the cryptographic signatures to make sure the code you got
was not intercepted and modified by an attacker.
Please head over to the [**Installing and
Verifying**](InstallingAndVerifying.md) documentation to get the code, and then
come back here to continue the tutorial.
Using the Library
------------------
I'm going to assume you know what symmetric encryption is, and the difference
between symmetric and asymmetric encryption. If you don't, I recommend taking
[Dan Boneh's Cryptography I course](https://www.coursera.org/learn/crypto/) on
Coursera.
To give you a quick introduction to the library, I'm going to explain how it
would be used in two sterotypical scenarios. Hopefully, one of these sterotypes
is close enough to what you want to do that you'll be able to figure out what
needs to be different on your own.
### Formal Documentation
While this tutorial should get you up and running fast, it's important to
understand how this library behaves. Please make sure to read the formal
documentation of all of the functions you're using, since there are some
important security warnings there.
The following classes are available for you to use:
- [Crypto](classes/Crypto.md): Encrypting and decrypting strings.
- [File](classes/File.md): Encrypting and decrypting files.
- [Key](classes/Key.md): Represents a secret encryption key.
- [KeyProtectedByPassword](classes/KeyProtectedByPassword.md): Represents
a secret encryption key that needs to be "unlocked" by a password before it
can be used.
### Scenario #1: Keep data secret from the database administrator
In this scenario, our threat model is as follows. Alice is a server
administrator responsible for managing a trusted web server. Eve is a database
administrator responsible for managing a database server. Dave is a web
developer working on code that will eventually run on the trusted web server.
Let's say Alice and Dave trust each other, and Alice is going to host Dave's
application on her server. But both Alice and Dave don't trust Eve. They know
Eve is a good database administrator, but she might have incentive to steal the
data from the database. They want to keep some of the web application's data
secret from Eve.
In order to do that, Alice will use the included `generate-defuse-key` script
which generates a random encryption key and prints it to standard output:
```sh
$ composer require defuse/php-encryption
$ vendor/bin/generate-defuse-key
```
Alice will run this script once and save the output to a configuration file, say
in `/etc/daveapp-secret-key.txt` and set the file permissions so that only the
user that the website PHP scripts run as can access it.
Dave will write his code to load the key from the configuration file:
```php
<?php
use Defuse\Crypto\Key;
function loadEncryptionKeyFromConfig()
{
$keyAscii = // ... load the contents of /etc/daveapp-secret-key.txt
return Key::loadFromAsciiSafeString($keyAscii);
}
```
Then, whenever Dave wants to save a secret value to the database, he will first
encrypt it:
```php
<?php
use Defuse\Crypto\Crypto;
// ...
$key = loadEncryptionKeyFromConfig();
// ...
$ciphertext = Crypto::encrypt($secret_data, $key);
// ... save $ciphertext into the database ...
```
Whenever Dave wants to get the value back from the database, he must decrypt it
using the same key:
```php
<?php
use Defuse\Crypto\Crypto;
// ...
$key = loadEncryptionKeyFromConfig();
// ...
$ciphertext = // ... load $ciphertext from the database
try {
$secret_data = Crypto::decrypt($ciphertext, $key);
} catch (\Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
// An attack! Either the wrong key was loaded, or the ciphertext has
// changed since it was created -- either corrupted in the database or
// intentionally modified by Eve trying to carry out an attack.
// ... handle this case in a way that's suitable to your application ...
}
```
Note that if anyone ever steals the key from Alice's server, they can decrypt
all of the ciphertexts that are stored in the database. As part of our threat
model, we are assuming Alice's server administration skills and Dave's secure
coding skills are good enough to stop Eve from being able to steal the key.
Under those assumptions, this solution will prevent Eve from seeing data that's
stored in the database.
However, notice that our threat model says nothing about what could happen if
Eve wants to *modify* the data. With this solution, Eve will not be able to
alter any individual ciphertext (because each ciphertext has its own
cryptographic integrity check), but Eve *will* be able to swap ciphertexts for
one another, and revert ciphertexts to what they used to be at previous times.
If we needed to defend against such attacks, we would have to re-design our
threat model and come up with a different solution.
### Scenario #2: Encrypting account data with the user's login password
This scenario is like Scenario 1, but subtly different. The threat model is as
follows. We have Alice, a server administrator, and Dave, the developer. Alice
and Dave trust each other, and Alice wants to host Dave's web application,
including its database, on her server. Alice is worried about her server getting
hacked. The application will store the users' credit card numbers, and Alice
wants to protect them in case the server gets hacked.
We can model the situation like this: after the server gets hacked, the attacker
will have read and write access to all data on it until the attack is detected
and Alice rebuilds the server. We'll call the time the attacker has access to
the server the *exposure window.* One idea to minimize loss is to encrypt the
users' credit card numbers using a key made from their login password. Then, as
long as the users all have strong passwords, and they are never logged in during
the exposure window, their credit cards will be protected from the attacker.
To implement this, Dave will use the `KeyProtectedByPassword` class. When a new
user account is created, Dave will save a new key to their account, one that's
protected by their login password:
```php
<?php
use Defuse\Crypto\KeyProtectedByPassword;
function CreateUserAccount($username, $password)
{
// ... other user account creation stuff, including password hashing
$protected_key = KeyProtectedByPassword::createRandomPasswordProtectedKey($password);
$protected_key_encoded = $protected_key->saveToAsciiSafeString();
// ... save $protected_key_encoded into the user's account record
}
```
Then, when the user logs in, Dave's code will load the protected key from the
user's account record, unlock it to get a `Key` object, and save the `Key`
object somewhere safe (like temporary memory-backed session storage). Note that
wherever Dave's code saves the key, it must be destroyed once the user logs out,
or else the attacker might be able to find users' keys even if they were never
logged in during the attack.
```php
<?php
use Defuse\Crypto\KeyProtectedByPassword;
// ... authenticate the user using a good password hashing scheme
// keep the user's password in $password
$protected_key_encoded = // ... load it from the user's account record
$protected_key = KeyProtectedByPassword::loadFromAsciiSafeString($protected_key_encoded);
$user_key = $protected_key->unlockKey($password);
$user_key_encoded = $user_key->saveToAsciiSafeString();
// ... save $user_key_encoded in the session
```
```php
<?php
// ... when the user is logging out ...
// ... securely wipe the saved $user_key_encoded from the system ...
```
When a user adds their credit card number, Dave's code will get the key from the
session and use it to encrypt the credit card number:
```php
<?php
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;
// ...
$user_key_encoded = // ... get it out of the session ...
$user_key = Key::loadFromAsciiSafeString($user_key_encoded);
// ...
$credit_card_number = // ... get credit card number from the user
$encrypted_card_number = Crypto::encrypt($credit_card_number, $user_key);
// ... save $encrypted_card_number in the database
```
When the application needs to use the credit card number, it will decrypt it:
```php
<?php
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;
// ...
$user_key_encoded = // ... get it out of the session
$user_key = Key::loadFromAsciiSafeString($user_key_encoded);
// ...
$encrypted_card_number = // ... load it from the database ...
try {
$credit_card_number = Crypto::decrypt($encrypted_card_number, $user_key);
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
// Either there's a bug in our code, we're trying to decrypt with the
// wrong key, or the encrypted credit card number was corrupted in the
// database.
// ... handle this case ...
}
```
With all caveats carefully heeded, this solution limits credit card number
exposure in the case where Alice's server gets hacked for a short amount of
time. Remember to think about the attacks that *aren't* included in our threat
model. The attacker is still free to do all sorts of harmful things like
modifying the server's data which may go undetected if Alice doesn't have secure
backups to compare against.
Getting Help
-------------
If you're having difficulty using the library, see if your problem is already
solved by an answer in the [FAQ](FAQ.md).

View file

@ -0,0 +1,51 @@
Upgrading From Version 1.2
===========================
With version 2.0.0 of this library came major changes to the ciphertext format,
algorithms used for encryption, and API.
In version 1.2, keys were represented by 16-byte string variables. In version
2.0.0, keys are represented by objects, instances of the `Key` class. This
change was made in order to make it harder to misuse the API. For example, in
version 1.2, you could pass in *any* 16-byte string, but in version 2.0.0 you
need a `Key` object, which you can only get if you're "doing the right thing."
This means that for all of your old version 1.2 keys, you'll have to:
1. Generate a new version 2.0.0 key.
2. For all of the ciphertexts encrypted under the old key:
1. Decrypt the ciphertext using the old version 1.2 key.
2. Re-encrypt it using the new version 2.0.0 key.
Use the special `Crypto::legacyDecrypt()` method to decrypt the old ciphertexts
using the old key and then re-encrypt them using `Crypto::encrypt()` with the
new key. Your code will look something like the following. To avoid data loss,
securely back up your keys and data before running your upgrade code.
```php
<?php
// ...
$legacy_ciphertext = // ... get the ciphertext you want to upgrade ...
$legacy_key = // ... get the key to decrypt this ciphertext ...
// Generate the new key that we'll re-encrypt the ciphertext with.
$new_key = Key::createNewRandomKey();
// ... save it somewhere ...
// Decrypt it.
try {
$plaintext = Crypto::legacyDecrypt($legacy_ciphertext, $legacy_key);
} catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex)
{
// ... TODO: handle this case appropriately ...
}
// Re-encrypt it.
$new_ciphertext = Crypto::encrypt($plaintext, $new_key);
// ... replace the old $legacy_ciphertext with the new $new_ciphertext
// ...
```

View file

@ -0,0 +1,260 @@
Class: Defuse\Crypto\Crypto
============================
The `Crypto` class provides encryption and decryption of strings either using
a secret key or secret password. For encryption and decryption of large files,
see the `File` class.
This code for this class is in `src/Crypto.php`.
Instance Methods
-----------------
This class has no instance methods.
Static Methods
---------------
### Crypto::encrypt($plaintext, Key $key, $raw\_binary = false)
**Description:**
Encrypts a plaintext string using a secret key.
**Parameters:**
1. `$plaintext` is the string to encrypt.
2. `$key` is an instance of `Key` containing the secret key for encryption.
3. `$raw_binary` determines whether the output will be a byte string (true) or
hex encoded (false, the default).
**Return value:**
Returns a ciphertext string representing `$plaintext` encrypted with the key
`$key`. Knowledge of `$key` is required in order to decrypt the ciphertext and
recover the plaintext.
**Exceptions:**
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
the platform the code is running on cannot safely perform encryption for some
reason (e.g. it lacks a secure random number generator), or the runtime tests
detected a bug in this library.
**Side-effects and performance:**
This method runs a small and very fast set of self-tests if it is the very first
time one of the `Crypto` methods has been called. The performance overhead is
negligible and can be safely ignored in all applications.
**Cautions:**
The ciphertext returned by this method is decryptable by anyone with knowledge
of the key `$key`. It is the caller's responsibility to keep `$key` secret.
Where `$key` should be stored is up to the caller and depends on the threat
model the caller is designing their application under. If you are unsure where
to store `$key`, consult with a professional cryptographer to get help designing
your application.
### Crypto::decrypt($ciphertext, Key $key, $raw\_binary = false)
**Description:**
Decrypts a ciphertext string using a secret key.
**Parameters:**
1. `$ciphertext` is the ciphertext to be decrypted.
2. `$key` is an instance of `Key` containing the secret key for decryption.
3. `$raw_binary` must have the same value as the `$raw_binary` given to the
call to `encrypt()` that generated `$ciphertext`.
**Return value:**
If the decryption succeeds, returns a string containing the same value as the
string that was passed to `encrypt()` when `$ciphertext` was produced. Upon
a successful return, the caller can be assured that `$ciphertext` could not have
been produced except by someone with knowledge of `$key`.
**Exceptions:**
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
the platform the code is running on cannot safely perform encryption for some
reason (e.g. it lacks a secure random number generator), or the runtime tests
detected a bug in this library.
- `Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException` is thrown if
the `$key` is not the correct key for the given ciphertext, or if the
ciphertext has been modified (possibly maliciously). There is no way to
distinguish between these two cases.
**Side-effects and performance:**
This method runs a small and very fast set of self-tests if it is the very first
time one of the `Crypto` methods has been called. The performance overhead is
negligible and can be safely ignored in all applications.
**Cautions:**
It is impossible in principle to distinguish between the case where you attempt
to decrypt with the wrong key and the case where you attempt to decrypt
a modified (corrupted) ciphertext. It is up to the caller how to best deal with
this ambiguity, as it depends on the application this library is being used in.
If in doubt, consult with a professional cryptographer.
### Crypto::encryptWithPassword($plaintext, $password, $raw\_binary = false)
**Description:**
Encrypts a plaintext string using a secret password.
**Parameters:**
1. `$plaintext` is the string to encrypt.
2. `$password` is a string containing the secret password used for encryption.
3. `$raw_binary` determines whether the output will be a byte string (true) or
hex encoded (false, the default).
**Return value:**
Returns a ciphertext string representing `$plaintext` encrypted with a key
derived from `$password`. Knowledge of `$password` is required in order to
decrypt the ciphertext and recover the plaintext.
**Exceptions:**
- `Defuse\Crypto\Exception\EnvironmentIsBrokenException` is thrown either when
the platform the code is running on cannot safely perform encryption for some
reason (e.g. it lacks a secure random number generator), or the runtime tests
detected a bug in this library.
**Side-effects and performance:**
This method is intentionally slow, using a lot of CPU resources for a fraction
of a second. It applies key stretching to the password in order to make password
guessing attacks more computationally expensive. If you need a faster way to
encrypt multiple ciphertexts under the same password, see the
`KeyProtectedByPassword` class.
This method runs a small and very fast set of self-tests if it is the very first
time one of the `Crypto` methods has been called. The performance overhead is
negligible and can be safely ignored in all applications.
**Cautions:**
PHP stack traces display (portions of) the arguments passed to methods on the
call stack. If an exception is thrown inside this call, and it is uncaught, the
value of `$password` may be leaked out to an attacker through the stack trace.
We recommend configuring PHP to never output stack traces (either displaying
them to the user or saving them to log files).
### Crypto::decryptWithPassword($ciphertext, $password, $raw\_binary = false)
**Description:**
Decrypts a ciphertext string using a secret password.
**Parameters:**
1. `$ciphertext` is the ciphertext to be decrypted.
2. `$password` is a string containing the secret password used for decryption.
3. `$raw_binary` must have the same value as the `$raw_binary` given to the
call to `encryptWithPassword()` that generated `$ciphertext`.
**Return value:**
If the decryption succeeds, returns a string containing the same value as the