Code Monkey home page Code Monkey logo

halite's Introduction

Halite

Build Status Static Analysis Latest Stable Version Latest Unstable Version License Downloads Coverage Status

Halite is a high-level cryptography interface that relies on libsodium for all of its underlying cryptography operations.

Halite was created by Paragon Initiative Enterprises as a result of our continued efforts to improve the ecosystem and make cryptography in PHP safer and easier to implement.

You can read the Halite Documentation online.

Halite is released under Mozilla Public License 2.0. Commercial licenses are available from Paragon Initiative Enterprises if you wish to extend Halite without making your derivative works available under the terms of the MPL.

If you are satisfied with the terms of MPL software for backend web applications but would like to purchase a support contract for your application that uses Halite, those are also offered by Paragon Initiative Enterprises.

Important: Earlier versions of Halite were available under the GNU Public License version 3 (GPLv3). Only Halite 4.0.1 and newer are available under the Mozilla Public License terms.

Installing Halite

Before you can use Halite, you must choose a version that fits the requirements of your project. The differences between the requirements for the available versions of Halite are briefly highlighted below.

PHP libsodium PECL libsodium Support
Halite 5.1 and newer 8.1.0 1.0.18 N/A (standard) ✔️ Active
Halite 5.0.x 8.0.0 1.0.18 N/A (standard) ✔️ Active
Halite 4.1+ 7.2.0 1.0.15 N/A (standard) ❌ Not Supported
Halite 4.0 7.2.0 1.0.13 N/A (standard) ❌ Not Supported
Halite 3 7.0.0 1.0.9 1.0.6 / 2.0.4 ❌ Not Supported
Halite 2 7.0.0 1.0.9 1.0.6 ❌ Not Supported
Halite 1 5.6.0 1.0.6 1.0.2 ❌ Not Supported

Note: Halite 5.0.x works on PHP 8.0, but performance is worse than on PHP 8.1.

If you need a version of Halite before 5.1, see the documentation relevant to that particular branch.

To install Halite, you first need to install libsodium. You may or may not need the PHP extension. For most people, this means running...

sudo apt-get install php7.2-sodium

...or an equivalent command for your operating system and PHP version.

If you're stuck, this step-by-step guide contributed by @aolko may be helpful.

Once you have the prerequisites installed, install Halite through Composer:

composer require paragonie/halite:^5

Commercial Support for Older Halite Versions

Free (gratis) support for Halite only extends to the most recent major version (currently 5).

If your company requires support for an older version of Halite, contact Paragon Initiative Enterprises to inquire about commercial support options.

If you need an easy way to migrate from older versions of Halite, check out halite-legacy.

Using Halite in Your Project

Check out the documentation. The basic Halite API is designed for simplicity:

Example: Encrypting and Decrypting a message

First, generate and persist a key exactly once:

<?php
use ParagonIE\Halite\KeyFactory;

$encKey = KeyFactory::generateEncryptionKey();
KeyFactory::save($encKey, '/path/outside/webroot/encryption.key');

And then you can encrypt/decrypt messages like so:

<?php
use ParagonIE\Halite\KeyFactory;
use ParagonIE\Halite\Symmetric\Crypto as Symmetric;
use ParagonIE\HiddenString\HiddenString;

$encryptionKey = KeyFactory::loadEncryptionKey('/path/outside/webroot/encryption.key');

$message = new HiddenString('This is a confidential message for your eyes only.');
$ciphertext = Symmetric::encrypt($message, $encryptionKey);

$decrypted = Symmetric::decrypt($ciphertext, $encryptionKey);

var_dump($decrypted->getString() === $message->getString()); // bool(true)

This should produce something similar to:

MUIDAEpQznohvNlQ-ZRk-ZZ59Mmox75D_FgAIrXY2cUfStoeL-GIeAe0m-uaeURQdPsVmc5XxRw3-2x5ZAsZH_es37qqFuLFjUI-XK9uG0s30YTsorWfpHdbnqzhRuUOI09c-cKrfMQkNBNm0dDDwZazjTC48zWikRHSHXg8NXerVDebzng1aufc_S-osI_zQuLbZDODujEnpbPZhMMcm4-SWuyVXcBPdGZolJyT

Cryptographic Keys in Halite

Important: Halite works with Key objects, not strings.

If you attempt to echo a key object, you will get an empty string rather than its contents. If you attempt to var_dump() a key object, you will just get some facts about the type of key it is.

You must invoke $obj->getRawKeyMaterial() explicitly if you want to inspect a key's raw binary contents. This is not recommended for most use cases.

Example: Generating a key from a password

<?php
use ParagonIE\Halite\KeyFactory;
use ParagonIE\HiddenString\HiddenString;

$passwd = new HiddenString('correct horse battery staple');
// Use random_bytes(16); to generate the salt:
$salt = "\xdd\x7b\x1e\x38\x75\x9f\x72\x86\x0a\xe9\xc8\x58\xf6\x16\x0d\x3b";

$encryptionKey = KeyFactory::deriveEncryptionKey($passwd, $salt);

A key derived from a password can be used in place of one randomly generated.

Example: Encrypting a large file on a system with low memory

Halite includes a file cryptography class that utilizes a streaming API to allow large files (e.g. gigabytes) be encrypted on a system with very little available memory (i.e. less than 8 MB).

<?php
use ParagonIE\Halite\File;
use ParagonIE\Halite\KeyFactory;

$encryptionKey = KeyFactory::loadEncryptionKey('/path/outside/webroot/encryption.key');

File::encrypt('input.txt', 'output.txt', $encryptionKey);

Common Support Issues

Uncaught SodiumException: Cannot Wipe Memory

PHP Fatal error: Uncaught SodiumException: This is not implemented, as it is not possible to securely wipe memory from PHP

The solution to this is to make sure libsodium is installed/enabled. See above in this README for more information.

Support Contracts

If your company uses this library in their products or services, you may be interested in purchasing a support contract from Paragon Initiative Enterprises.

halite's People

Contributors

alexekorn avatar blaaat avatar clayfreeman avatar elliot-sawyer avatar faizanakram99 avatar hansott avatar j-d avatar junaidbinfarooq avatar klemens-u avatar larowlan avatar mathroc avatar nenglish7 avatar omatamix avatar paragonie-scott avatar paragonie-security avatar pavarnos avatar prisis avatar steffi-s avatar tittlejonathan avatar usmanmetronome avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

halite's Issues

Parameter values for functions KeyFactory?

What is the point of the parameters for the functions in KeyFactory? All of the functions there are like below:

    public static function generateAuthenticationKey(string &$secretKey = ''): AuthenticationKey
    {
        $secretKey = \Sodium\randombytes_buf(
            \Sodium\CRYPTO_AUTH_KEYBYTES
        );
        return new AuthenticationKey(
            new HiddenString($secretKey)
        );
    }

Would that not make the parameters $secretKey superfluous to pass along? I would refactor the first line like so:

    if (is_null($secretKey) || strlen($secretKey) <= \Sodium\CRYPTO_AUTH_KEYBYTES) {
        $secretKey = \Sodium\randombytes_buf(
            \Sodium\CRYPTO_AUTH_KEYBYTES
        );
    }

This goes for functions:

  • generateAuthenticationKey
  • generateEncryptionKey
  • generateEncryptionKeyPair
  • generateSignatureKeyPair

============================

Next, this function deriveAuthenticationKey expects a salt of exactly 16 chars, based on (Util::safeStrlen($salt) !== \Sodium\CRYPTO_PWHASH_SALTBYTES) comparison. Is this done with a reason? (limitations/design/etc?) Else I wouldn't mind passing along a larger salt, e.g. 32 or 64 chars.

This question goes for functions:

  • deriveAuthenticationKey
  • deriveEncryptionKey
  • deriveEncryptionKeyPair
  • deriveSignatureKeyPair

compitible with php5.5.9

Hello, I do some work to make it compitible with php5.5.9. I don`t know whether it is OK to merge my work into your branch. #52

Libsodium not available in PHPStorm

I see you have a beautiful Sodium stub in this package. It is possible to create a PR here to embed this directly into PHPStorm. Would you be so kind to create the PR? Or, for sure, I can create it for you, if you give me permission to do so.

Compile Error in Symmetric Crypto

I recently started using Password hashing function which seems very promising in my web app which happens to be using Symfony framework, however it appears that the Symmetric Crypto file is giving a Compile Error as per the debug component (which comes very handy to debug common bugs etc).

This is the exact error given by Symfony debug component.

Compile Error: Cannot use ParagonIE\Halite\Config as Config because the name is already in use

Here is the stack trace that can provide more insight into the problem.

  1. Entry level: i am calling the verify method in my code.
    Password::verify($password, $hash, $this->encKey);
  2. This hits the verify function in paragonie/halite/src/Password.php (line 155)
    $hash_str = Crypto::decrypt($stored, $secretKey);
  3. This hits the paragonie/halite/src/Symmetric/Crypto.php and gives the above mentioned error. Specific code that gets highlighted is
    use ParagonIE\Halite\{ Config,

Solution: It appears that we do not require base Config to be referred in paragonie/halite/src/Symmetric/Crypto.php as Symmetric / Config is the one which should be doing most of the job here anyways. Secondly, splitKey function should use SymmetricConfig as required parameter rather then Config (line 196)

Let me know if above solution makes sense and i can send a quick PR.

Lastly great work by @paragonie-scott - this lib makes crypto such a pain free process.

compileerror

\ParagonIE\Halite\File::decrypt fails when running on laravel homestead

I am having issues using this library for encrypting / decrypting files.

What is strange is that everything works as expected when running PHP via the cli. Yet running it through nginx (php-fpm) seems to cause issues and the decryption fails consistently with the following error:

Fatal error: Uncaught ParagonIE\Halite\Alerts\InvalidMessage: Invalid message authentication code

I am running running PHP 7 on the laravel homestead environment.

I narrowed it down to the following script:

<?php

require_once __DIR__ . '/../vendor/autoload.php';

@mkdir(__DIR__ . '/enc/');
file_put_contents(__DIR__ . '/enc/test.txt', 'This is a test');

$key = \ParagonIE\Halite\KeyFactory::deriveEncryptionKey('password', str_repeat('a', 16));
@unlink(__DIR__ . '/enc/encrypted');
@unlink(__DIR__ . '/enc/decrypted.txt');

\ParagonIE\Halite\File::encrypt(__DIR__ . '/enc/test.txt', __DIR__ . '/enc/encrypted', $key);
\ParagonIE\Halite\File::decrypt(__DIR__ . '/enc/encrypted', __DIR__ . '/enc/decrypted.txt', $key);

\ParagonIE\Halite\Halite::isLibsodiumSetupCorrectly() returns true

The following

var_dump([
    $major = \Sodium\library_version_major(),
    $minor = \Sodium\library_version_minor(),
]);

outputs array(2) { [0]=> int(9) [1]=> int(2) }

And I followed the instructions to compile libsodium from the source from this blog article:
https://paragonie.com/book/pecl-libsodium/read/00-intro.md

Thanks in advance

Version 2.1.0 Plan (and Call for Wishlist Items)

  • Allow KeyFactory to accept a "security level" argument for key derivation:
    • Scrypt: INTERACTIVE, SENSITIVE
    • Argon2i: INTERACTIVE, MODERATE, SENSITIVE
  • Allow MerkleTree to accept an output size and personalization string.
  • Clean up Key definitions (thanks @Vinai)
  • Add cost parameter to Password

If anyone was hoping for anything else to be added to this list, now's the time to make your suggestions/requests.

Either reply here or make a feature request issue. I'll tag appropriately.

Issue during installation of Airship CMS

i successfully install php7.2
now going to install libsodium from this link https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium

after installing i tried phpenmod libsodium and it gives following error
WARNING: Module libsodium ini file doesn't exist under /etc/php/7.0/mods-available`

now i goto airship cms install and type composer install
`Your requirements could not be resolved to an installable set of packages.

Problem 1
- The requested PHP extension ext-libsodium ^1.0.6 is missing from your system. Install or enable PHP's libsodium extension.
Problem 2
- Installation request for paragonie/halite v2.2.0 -> satisfiable by paragonie/halite[v2.2.0].
- paragonie/halite v2.2.0 requires ext-libsodium ^1.0.6 -> the requested PHP extension libsodium is missing from your system.

To enable extensions, verify that they are enabled in those .ini files:
- /etc/php/7.0/cli/php.ini
- /etc/php/7.0/cli/conf.d/10-opcache.ini
- /etc/php/7.0/cli/conf.d/10-pdo.ini
- /etc/php/7.0/cli/conf.d/15-xml.ini
- /etc/php/7.0/cli/conf.d/20-calendar.ini
- /etc/php/7.0/cli/conf.d/20-ctype.ini
- /etc/php/7.0/cli/conf.d/20-dom.ini
- /etc/php/7.0/cli/conf.d/20-exif.ini
- /etc/php/7.0/cli/conf.d/20-fileinfo.ini
- /etc/php/7.0/cli/conf.d/20-ftp.ini
- /etc/php/7.0/cli/conf.d/20-gd.ini
- /etc/php/7.0/cli/conf.d/20-gettext.ini
- /etc/php/7.0/cli/conf.d/20-iconv.ini
- /etc/php/7.0/cli/conf.d/20-json.ini
- /etc/php/7.0/cli/conf.d/20-mbstring.ini
- /etc/php/7.0/cli/conf.d/20-phar.ini
- /etc/php/7.0/cli/conf.d/20-posix.ini
- /etc/php/7.0/cli/conf.d/20-readline.ini
- /etc/php/7.0/cli/conf.d/20-shmop.ini
- /etc/php/7.0/cli/conf.d/20-simplexml.ini
- /etc/php/7.0/cli/conf.d/20-sockets.ini
- /etc/php/7.0/cli/conf.d/20-sysvmsg.ini
- /etc/php/7.0/cli/conf.d/20-sysvsem.ini
- /etc/php/7.0/cli/conf.d/20-sysvshm.ini
- /etc/php/7.0/cli/conf.d/20-tokenizer.ini
- /etc/php/7.0/cli/conf.d/20-wddx.ini
- /etc/php/7.0/cli/conf.d/20-xmlreader.ini
- /etc/php/7.0/cli/conf.d/20-xmlwriter.ini
- /etc/php/7.0/cli/conf.d/20-xsl.ini
- /etc/php/7.0/cli/conf.d/20-zip.ini
You can also run php --ini inside terminal to see which files are used by PHP in CLI mode.
`

i tried to install it more that 20 times and evrytime same errror libsodium
any help?

Enable memory-only key persistence

For version 2 and 3:

Update KeyFactory to support loading/saving keys to an encoded/serialized string format. We'll probably use the exact same structure as saving to a file.

In version 2: work with strings.
In version 3: work with HiddenString objects.

This will be released as 2.2.0 and 3.1.0, respectively.

Suggestion for HiddenString

I would like that HiddenString cannot be revealed via serialize(...); this can be achieved by the __sleep() magic method returning an empty array. Would this fit within the scope of what HiddenString sets out to achieve?

Feedback Sought From Halite Users

I'm considering whether to flag the API as stable and put this in "maintenance only" mode in Paragon's internal docs, but before I do, what (if anything) does Halite currently not do that you'd like to see it do before it's done?

Call to undefined function Sodium\randombytes_buf()

Getting this error with circlical and zf3 on a vagrant machine ubuntu 16.04

vagrant@vagrant:/usr/lib/php/20151012$ pecl search libsodium
Retrieving data...0%
Matched packages, channel pecl.php.net:
=======================================
Package   Stable/(Latest) Local
libsodium 1.0.6 (stable)  1.0.6 Wrapper for the Sodium cryptographic library
vagrant@vagrant:/usr/lib/php/20151012$ apt-cache policy libsodium-dev
libsodium-dev:
  Installed: 1.0.8-5
  Candidate: 1.0.8-5
  Version table:
 *** 1.0.8-5 500
        500 http://us.archive.ubuntu.com/ubuntu xenial/universe amd64 Packages
        100 /var/lib/dpkg/status

/var/www/vendor/paragonie/halite/src/KeyFactory.php:51

Call to undefined function Sodium\randombytes_buf()

#0 /var/www/vendor/saeven/zf3-circlical-user/src/CirclicalUser/Service/AuthenticationService.php(542): ParagonIE\Halite\KeyFactory::generateEncryptionKey()
#1 /var/www/module/Application/src/Service/AdminService.php(60): CirclicalUser\Service\AuthenticationService->registerAuthenticationRecord(Object(Application\Entity\User), 'bluebaroncanada...', 'test')
#2 /var/www/module/Application/src/Controller/AdminController.php(46): Application\Service\AdminService->createUser('bluebaroncanada...', 'test', true)
#3 /var/www/vendor/zendframework/zend-mvc/src/Controller/AbstractActionController.php(78): Application\Controller\AdminController->createUserAction()
#4 /var/www/vendor/zendframework/zend-eventmanager/src/EventManager.php(322): Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#5 /var/www/vendor/zendframework/zend-eventmanager/src/EventManager.php(179): Zend\EventManager\EventManager->triggerListeners(Object(Zend\Mvc\MvcEvent), Object(Closure))
#6 /var/www/vendor/zendframework/zend-mvc/src/Controller/AbstractController.php(105): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#7 /var/www/vendor/zendframework/zend-mvc/src/DispatchListener.php(119): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#8 /var/www/vendor/zendframework/zend-eventmanager/src/EventManager.php(322): Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#9 /var/www/vendor/zendframework/zend-eventmanager/src/EventManager.php(179): Zend\EventManager\EventManager->triggerListeners(Object(Zend\Mvc\MvcEvent), Object(Closure))
#10 /var/www/vendor/zendframework/zend-mvc/src/Application.php(332): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#11 /var/www/public/index.php(49): Zend\Mvc\Application->run()
#12 {main}

How to install halite on ubuntu 16.04 and php7

Assuming that you don't have build utils, php7 devtools, git, pear&pecl, composer (fresh install)

Libsodium

  1. Get build utils
    sudo apt-get install build-essential
  2. Get php7.0-dev
    sudo apt-get install php7.0-dev
    Or php7.1-dev/php7.2-dev
    sudo apt-get install php7.1-dev
    sudo apt-get install php7.2-dev
  3. Git (good)
    sudo apt-get install git
  4. Get libsodium
# Clone the libsodium source tree & Build libsodium, perform any defined tests, install libsodium
git clone -b stable https://github.com/jedisct1/libsodium.git && cd libsodium && ./configure && make check && make install
  1. Get PEAR & PECL
    sudo apt-get install pear
  2. Install libsodium from PECL
    pecl install libsodium (or pecl install -f libsodium-2.0.8 according to comments)
  3. Get straight to /etc/php/<PHP_VERSION>/mods-available/ and make a libsodium.ini file (Where <PHP_VERSION> is 7.0 or 7.1 or 7.2)
  4. Write down extension=libsodium.so (or sodium.so according to comments) in libsodium.ini & save (Yes, it works like this now, no more php.ini bs)
  5. Enable the libsodium mod
    sudo phpenmod libsodium
  6. Reload PHP
    sudo /etc/init.d/apache2 restart && service php7.0-fpm restart
  7. Check for libsodium with php -m

Halite

  1. Get composer
    sudo apt-get install composer
  2. Navigate to your php project folder and install halite
    composer require paragonie/halite
  3. Done

Split keys further?

Currently, you have three main Key derivatives to work with:

  • \ParagonIE\Halite\Symmetric\SecretKey
  • \ParagonIE\Halite\Asymmetric\PublicKey
  • \ParagonIE\Halite\Asymmetric\SecretKey

But each of these can be a key intended for encryption or for authentication/digital signatures, which is determined by a boolean constructor argument.

Proposal: Further split into different types.

  • \ParagonIE\Halite\Symmetric\SecretKey
    • \ParagonIE\Halite\Symmetric\AuthenticationKey
    • \ParagonIE\Halite\Symmetric\EncryptionKey
  • \ParagonIE\Halite\Asymmetric\PublicKey
    • \ParagonIE\Halite\Asymmetric\EncryptionPublicKey
    • \ParagonIE\Halite\Asymmetric\SignPublicKey
  • \ParagonIE\Halite\Asymmetric\SecretKey
    • \ParagonIE\Halite\Asymmetric\EncryptionSecretKey
    • \ParagonIE\Halite\Asymmetric\SignSecretKey

This change will be introduced by adding classes and changing the object type returned by Key::generate(), etc. The existing classes will not be removed.

crypto_box_seal is not available

when I use Halite\Asymmetric\Crypto::seal it throw exception crypto_box_seal is not available I had a look into the method and function_exists('\Sodium\crypto_box_seal') return false when it has leading slash but function_exists('Sodium\crypto_box_seal') it return true

i am using Halite 1.0.5

Composer install fails

A number of errors of this nature...

!! PHP Fatal error: Cannot redeclare Sodium\crypto_aead_aes256gcm_is_available() (previously declared in vendor/paragonie/sodium_compat/lib/sodium_compat.php:70) in vendor/paragonie/halite/stub/Sodium.stub.php on line 70

Version 1.0.0 Roadmap

Version 1.0.0 Roadmap:

Mainline Features

  • Key encapsulation
    • Key
    • Asymmetric\SecretKey
    • Asymmetric\PublicKey
    • KeyPair
    • Symmetric\SecretKey
  • String encryption/decryption
    • Symmetric-key
    • Asymmetric-key
  • Cookie encryption/decryption
  • Message signing
    • Symmetric-key (HMAC)
    • Digital signatures (EdDSA)
  • File encryption/decryption
    • Symmetric-key
    • Asymmetric-key
    • Streaming checksum calculation
  • File authentication #13
    • Asymmetric-key authentication (digital signature)
  • Password management
    • Secure storage (hash-then-encrypt)
    • Secure verification (verify MAC, decrypt, verify password)

To Do Before Tagging 1.0.0

  • Fix that strange PHP 7 error.
  • Complete Documentation

Possibly Before 1.0.0

  • Launch an Interactive Downloadable Tutorial (separate project?)
  • External audit
  • Demo/Example Code

Release Schedule

  • Version 0.6.0 (2015-10-24)
    • First beta release
    • Code freeze (outside of creating unit tests)
  • Version 0.N.0 (for N > 6) ...
    • Amend anything that is broken until it ceases to break...
  • Version 1.0.0 (2015-11-06)
    • Remove support for v0.x

Network Stream and AEAD

Placeholder ticket. Investigate the usefulness of having:

  • ParagonIE\Halite\Network\
    • NonceProvider\
      • PDOProvider
      • RandomProvider
      • ProviderInterface
        • getNonce() get a nonce and increase the stored value (for PDO)
    • Crypto
      • encrypt() using \Sodium\crypto_aead_encrypt() after CAESAR
      • decrypt() using \Sodium\crypto_aead_decrypt() after CAESAR
      • Would require a nonce provider, which is stateful

This might be a useless idea. You should be using TLS.

Running unit tests fail upon downloading PGP key

I tried to run the unit tests and got this error:

[firexware@firexware-pc halite]$ ./test/phpunit.sh 
gpg: error reading key: No public key
Downloading PGP Public Key...
gpg: keyserver receive failed: No keyserver available
gpg: error reading key: No public key
Could not download PGP public key for verification

Maybe a keyserver should be specified explicitly in the script?

Documentation confusing for KeyFactory::deriveEncryptionKey in Halite1

Documentation mentions the following

https://github.com/paragonie/halite#example-generating-a-key-from-a-password

Relevant Excerpt:

$salt = "\xdd\x7b\x1e\x38\x75\x9f\x72\x86\x0a\xe9\xc8\x58\xf6\x16\x0d\x3b";

$encryptionKey = KeyFactory::deriveEncryptionKey($passwd, $salt);

In Halite1 the salt needs to be binary format not a hex encoded string. Or else you will get the exception:

salt should be CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes

Documentation

The API has changed since 0.3.0; keys are simpler to use. Let's update everything then add more coverage.

Block Chain Data Structure?

See #23 for a prerequisite.

Someone might decide to reinvent the wheel here. We should consider providing this so someone doesn't shoot themselves in the foot.

Use AEAD for Password Hashing API

In version 4, we should make it easy to tie encrypted password hashes to specific user accounts. A simple win is to change from an AE mode to an AEAD mode (i.e. XChaCha20-Poly1305), and allow the additional data to be passed to the interface.

  • ParagonIE\Halite\Symmetric\Crypto would gain an AEAD interface.
  • ParagonIE\Halite\Password would gain an optional extra string argument to both hash() and verify().

KeyFactory::generateEncryptionKey returning nothing

PHP 7.1.8 (cli) (built: Aug 17 2017 14:29:52) ( NTS
halite 3.2.0

Am I doing something stupid ?

$enc_key = \ParagonIE\Halite\KeyFactory::generateEncryptionKey();
echo strlen($enc_key).PHP_EOL;

Seems to return zero ? Base64 wrapping $enc_key returns nothing ? Have I missed a step ?

A signing key is generated when trying to generate an encryption key when deriving from password

Taking simple case from docs. When creating a symmetric encryption key it actually generates a signing key due to missing parenthesis. Operator precedence in PHP evaluates !== operator before & operator.

$salt = \Sodium\hex2bin(
    '762ce4cabd543065172236de1027536ad52ec4c9133ced3766ff319f10301888'
);

$enc_secret = Key::deriveFromPassword(
    'correct horse battery staple',
    $salt,
    Key::ENCRYPTION | Key::SECRET_KEY
);

Fatal error with Sodium\hex2bin

Our PHP application is working correctly with Halite 1.0 on PHP 5.6 and corresponding Libsodium and PECL Libsodium.

Recently, we started migrating our application to Halite v3.2.0, and we are receiving error, as below,

Fatal error: Uncaught Error: Call to undefined function Sodium\hex2bin() in /home/uatpgsw/app/includes/halite-v320/src/KeyFactory.php:676
Stack trace:
#0 /home/uatpgsw/app/includes/halite-v320/src/KeyFactory.php(587): ParagonIE\Halite\KeyFactory::loadKeyFile('/home/uatpgsw/g...')
#1 /home/uatpgsw/public_html/index.php(267): ParagonIE\Halite\KeyFactory::loadEncryptionKeyPair('/home/uatpgsw/g...')
#2 {main}
thrown in /home/uatpgsw/app/includes/halite-v320/src/KeyFactory.php on line 676

Our dev system has:

  • PHP v7.0.26
  • Libsodium: v1.0.9
  • PECL libsodium v2.0.10

When I run the following:

<?php var_dump([ SODIUM_LIBRARY_MAJOR_VERSION, SODIUM_LIBRARY_MINOR_VERSION, SODIUM_LIBRARY_VERSION ]); ?>

the response is as follows:

array(3) { [0]=> int(9) [1]=> int(6) [2]=> string(6) "1.0.14" }

Please share, if I am missing something or do we specifically need to use the older versions like PECL Libsodium 1.0.6 / 2.0.4, along with PHP v7.0 and Libsodium v1.0.9, as documented in https://github.com/paragonie/halite?

thank you

Open halite to the community

PHP 7.2 is behind the doors and many of us will switch to sodium as our encryption library. It is not easy to use so we will look for a higher level interface. Halite is currently only one doing this job and it is doing it really well. But is unusable for majority of projects because of license.
That majority cannot use GPLv3 licensed libraries. Please, give us choice to use another license by default instead of offering commercial licenses. We cannot rely on just a chance of obtaining non-gpl license.
We need to know there is a encryption library we can use everytime with all our projects. And if halite is not library which allow it, community will create alternatives. Why we should do it when perfect library currently exists?

[RFC] Include the password expiration timestamp with the encrypted hash

This is an idea I came-up with a few days ago after reading https://paragonie.com/blog/2016/09/untangling-forget-me-knot-secure-account-recovery-made-simple

However, even if you apply this mitigation, there's nothing preventing an attacker from just replacing one user's password hash with their own (unique constraints on the database column don't help here; simply change your own password then set the target's to your old password hash, for which you know the correct password).

To prevent someone from re-setting an expired password, would it make sense to include the expiration timestamp with the encrypted password-hash?

With Halite the password is first crypto-hashed and then encrypted with a key.
If you include the expiration timestamp with the encrypted hash: time-stamp:hash -> encrypt, it would still be possible to re-set the password to a known hash, but after decryption the system will refuse the give an OK as the password is (eventually) expired.
And the attacker shouldn't know the encryption key, and thus is not able to create a correct result.

I'm no security expert, so I would like hear your opinion on this idea 👍

Always rehashing with PHP7.2 (Argon2i vs Argon2id)

When moving towards PHP 7.2 and upgrading from \Sodium::CONSTANT towards SODIUM_CONSTANT, I was noticing that the password hashing mechanism was changed from Argon2i to Argon2id. At first I thought that might be just my configuration, but I also see it on 3v4l.

If this is not configuration, it means that Halite is always rehashing passwords in PHP7.2, because it counts on Argon2i. Or am I just missing something?

Merkle Tree

Add a Merkle tree implementation that uses the BLAKE2b hash function.

Specifically:

  • Mark leaf nodes differently from branches, to prevent second preimage attacks.

libsodium vs sodium

Hi,

I've followed this guide to install the php extension: https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-extension

This installed an extension called sodium, not libsodium (ref: https://github.com/jedisct1/libsodium-php)

While when trying to add paragonie/halite via composer, the command failed with an error:
" paragonie/halite dev-master requires ext-libsodium ^1.0.6 -> the requested PHP extension libsodium is missing from your system."

Checking the composer.json file in master reveals that the old libsodium (v1.x) is still required, and installing the latest "sodium" lib doesn't work.

    "require": {
        "php": "^7",
        "paragonie/constant_time_encoding": "^2",
        "ext-libsodium": "^1.0.6"
    },

note: This might be linked to an existing issue: #51

File - Stream Authentication

We should add some new methods to the File API:

  • signFile() - Ed25519 signature of an unkeyed BLAKE2b hash of the file
  • macFile() - keyed BLAKE2b hash
  • verifyFileMac()
  • verifyFileSignature()

I need to think of better names for the last two.

Also, s/File/Resource/.

Syntax error in Key.md

In the GitHub rendering, it looks like:

$raw
$encryption_key = Key::generate(Key::CRYPTO_SECRETBOX, $raw);
if (hash_equals($encryption_key->get(), $raw)) {
    // This should always return true
}

That $raw looks like a syntax error to me.

Peer Review Sought Before v2.0.0 is Tagged

Version 2 uses strict typing. This led to a lot of code deletion and API simplification. The diffs:

Before I proceed to tag version 2.0.0, I'd like to be sure of a few things:

  1. Did I avoid introducing any vulnerabilities since 1.0.0?
  2. Are there any more breaking changes that need to be made?
  3. Are there any more features that anyone absolutely needs before we commit to a code freeze?
  4. Are the new data structures (MerkleTree and BlockChain) sanely implemented?

I'll probably end up answering most of these questions myself, but if anyone would like to weigh in, please feel free.

Note: The unit tests are currently failing in master because I wrote these changes against dev-master of both libsodium and libsodium-php. As soon as the new release comes out, the tests will pass (I hope!).

Documentation is confusing with regards to HiddenString

---IGNORE THIS COMMENT---

This isn't an issue, but an earlier discussion said to ask for help here, so:

I'm trying to run a pretty simple Halite example (shown below).

<?php
require_once 'vendor/autoload.php';

use ParagonIE\Halite\HiddenString;
use ParagonIE\Halite\KeyFactory;
use ParagonIE\Halite\Symmetric\Crypto as Symmetric;

$encryptionKey = KeyFactory::loadEncryptionKey('/var/key/9.key');

$message = new HiddenString('This is a confidential message for your eyes only.');
$ciphertext = Symmetric::encrypt($message, $encryptionKey);

$decrypted = Symmetric::decrypt($ciphertext, $encryptionKey);

var_dump($decrypted === $message); // bool(true)

?>

However, the program always breaks at new HiddenString();, for a reason that I can't seem to understand. If anyone has any insight, or can offer any help, that would be most appreciated. Thank you so much!

Debian Jessie
Raspberry Pi Model B
PHP 5.6.24-0+deb8u1
Halite: v1.5.1
PECL extention: v1.0.6
Composer: v1.2.0

Thanks!

Vulnerable to Spectre + Meltdown

Hello,

Because libsodium has made strong efforts to prevent side-channel compromises, do you know if the added protection in this library would prevent or at least inhibit the effectiveness of an exploit on the system using Meltdown or Spectre?

On the surface it would see that the answer to this question is "probably no", however I wonder if the great effort that libsodium has go to, in order to protect memory space; that this library and other libsodium projects are immune or "not as vulnerable" to these types of attacks.

Looking forward to your response,
Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.