Paragon Initiative Enterprises Blog

The latest information from the team that develops cryptographically secure PHP software.

Slice Of PIE #01

Today, we answer some reader questions about secure credential management, the benefits of ChaCha and BLAKE2 over AES and SHA2, and fault attacks on EdDSA.

Logo: Slice of PIE #01

Secure Credential Management in PHP Applications

Received via Twitter:

Is there any improvement wrt protecting database passwords in PHP applications, beyond not having passwords in repositories, and storing them in read-only files outside of webroot?

Chris Cornutt of websec.io wrote a two-part series about this topic (1 2).

If you don't want to go all in on the encryption + Docker solution that Chris identified, there's a simple and elegant way to stop most credential theft attacks.

Important: Threat models matter here a lot.

If your app has an RCE bug, and your app can connect to the database, there's nothing stopping malicious users from getting your database password.

Decide what threats you want to address in your design, and solve the remaining ones at a different layer.

With that in mind, a generic solution for the most common threat model and architecture looks like this:

  1. Use objects (or use our hidden-string package) to encapsulate your sensitive string data.
  2. Write a PHP file that returns an object, and use require to load it into your app once.

For PHP apps that load everything into their document root (e.g. WordPress sites), this is more secure than a .env file, since it's very unlikely that you'll be able to trick Apache into coughing up the source code.

For example, if you make a file named config_file.php like so:

<?php
use ParagonIE\HiddenString\HiddenString;

return [
    'database-password' => new HiddenString(/* Fill me in */),
    'imap-password' => new HiddenString(/* Fill me in */),
];

...then you can load it in at runtime:

$config = require "config_file.php";

Make sure you exclude these PHP files from version control.

Modern Cryptography in a Nutshell

Received via Twitter:

What's a good TLDR for modern algs like Salsa20, ChaCha, Blake2b? I have a good understanding of RSA, ECC, AES, SHA, etc. What do they offer as improvements? Why should they be chosen?

TL;DR - What these algorithms offer is speed and security, without requiring specialized hardware.

The algorithms in question share a lineage: Salsa20 was an eSTREAM finalist created by Daniel J. Bernstein. ChaCha is slightly faster on most platforms, and has better diffusion. BLAKE2b is a hash function based on the ChaCha round function. Today, you're probably going to choose ChaCha and BLAKE2b, but not Salsa20, unless you need interoperability with a Salsa20-based system (i.e. TweetNaCl).

Salsa20/ChaCha vs AES

AES implemented in software is very slow, or it's vulnerable to cache-timing attacks. In order to make AES performant, hardware acceleration is used in most computers (but not older mobile devices).

ChaCha is always fast, always constant-time.

To do a fair comparison, you'll need a pure software (no AES-NI) implementation of AES that doesn't use table look-ups (to avoid cache-timing side channel attacks) to contrast ChaCha with. Otherwise, your AES implementation is sacrificing security, which is unacceptable in the real world.

A benchmark comparison by CloudFlare of AES-GCM vs ChaCha20-Poly1305 yielded the following results:

AES-128-GCM: 		41.6ms
ChaCha20-Poly1305: 	13.2ms

Assuming a secure implementation (minimum 128-bit security level, no side-channels) ChaCha20-Poly1305 offers better performance (and, for mobile users, battery life) than AES-based ciphersuites.

Otherwise, for at least 99% of users in the world, they're both secure.

Note: Unless something has changed recently, AES-NI is only available for 128-bit AES on most chips. This is because each round key needs to occupy a register (for which only 16 are available), and AES-128 has 10 rounds while AES-192 and AES-256 have 12 and 14 respectively. ChaCha20 has no further caveats: It's always targeting the 256-bit security level.

BLAKE2b vs SHA2

The main selling point of BLAKE2b is that it's very fast. How fast?

BLAKE2b Benchmarks from BLAKE2.net

BLAKE2b is faster than MD5 and at least as secure as SHA3, which is in turn believed to be more secure than SHA2. (Image from BLAKE2b.net, which has more information about the hash function and its design.)

New Intel chips ship with hardware-accelerated SHA instructions will offer better performance for SHA1 (which is broken) and SHA256. If your application needs SHA512 hashes (i.e. Ed25519 signature generation), the new hardware features will not benefit you.


Their follow-up tweet adds:

To add onto this, I find platform support for RSA/ECC/AES/SHA is usually much better, especially at the hardware level. For mobile apps, Android only supports storing RSA keypairs in the hardware-backed keystore (it says it supports ECC but we had issues), and iOS both ECC/RSA.

The simple reason for this is that hardware support for cryptography is lagging behind the trends in software.

It wasn't until recently that an HSM existed that supported Ed25519, but now one does, and hopefully other vendors follow suit.

The Android ecosystem suffers from the horrendous legacy that is javax.crypto.Cipher. Hopefully projects like Tink significantly improve the cryptography available to Android developers.

If not, hopefully iOS will lead the way on secure cryptography in the mobile space.

Fault Attacks on Deterministic Signature Schemes i.e. Ed25519

Received via email:

Kudelski published a paper detailing fault attacks on Ed25519. How important are these attacks to protect against, and how can I do so?

This is the domain of smart cards and similar hardware products. If you're dealing with specialized hardware, you shouldn't be outsourcing your cryptography decisions to blog posts. If you're not dealing with specialized hardware, fault attacks aren't really in scope and you shouldn't worry about them at all.

Virtually nobody breaks web applications with fault attacks. If you work with PHP, you'll almost certainly never need to worry about fault attacks, unless you're an extreme corner case.

For anyone working with specialized hardware, if you're using libsodium, you can build it with the ED25519_NONDETERMINISTIC macro defined. This will add random noise to the computation of EdDSA nonces, but it breaks RFC 8032 compatibility.

Kudelski's paper also outlines other mitigation strategies, which are probably not worth implementing in most systems.

What if you wanted randomized Ed25519 signatures without breaking RFC 8032 compatibility?

Important: This probably won't stop attackers from injecting hardware faults and recovering enough information to forge signatures.

It's actually possible to implement randomized Ed25519 signatures without breaking RFC 8032 or NaCl API compatibility, in a higher-level API.

For example, consider the following PHP functions (also available on 3v4l):

<?php
declare(strict_types=1);

/**
 * IMPORTANT:
 *
 * These functions are provided for educational purposes only, and are
 * provided without warranty or liability.
 */
define('SODIUM_CRYPTO_RSIGN_SIGBYTES', 96);

function sodium_crypto_rsign(string $message, string $sk): string
{
    return sodium_crypto_sign(random_bytes(32) . $message, $sk);
}

function sodium_crypto_rsign_open(string $sm, string $pk): string
{
    $opened = sodium_crypto_sign_open($sm, $pk);
    return mb_substr($opened, 32, null, '8bit');
}

function sodium_crypto_rsign_detached(string $message, string $sk): string
{
    $random = random_bytes(32);
    return sodium_crypto_sign_detached($random . $message, $sk) . $random;
}

function sodium_crypto_rsign_verify_detached(string $signature, string $message, string $pk): bool
{
    $sig = mb_substr($signature, 0, 64, '8bit');
    $random = mb_substr($signature, 64, 32, '8bit');
    return sodium_crypto_sign_verify_detached($sig, $random . $message, $pk);
}

These functions (named rsign because they're randomized signatures) change the Ed25519 API from signing a message to signing 32 random bytes followed by a message. These random bytes aren't provided by the user, they're implicit to the function's design.

  • In crypto_sign(), the output format is $signature . $message (this is what NaCl/libsodium provides).
  • In crypto_rsign(), the output format is $signature . $random . $message.

In the detached API, these random bytes are appended to the signature instead of prepended to the message.

How to Send in Questions for Slice of PIE?

  • Send an email to sliceofpie@paragonie.com with your questions.
  • Tweet/DM your questions to @ParagonIE with the hashtag, #SliceOfPIE.

Emails and tweets sent to other email addresses and/or without the hashtag will not, by default, be considered for inclusion in this series.

About the Author

Scott Arciszewski

Chief Development Officer

With 15 years of software development, application security, and system administration experience, Scott aspires to help others attain a happier work-life balance by solving difficult problems and automating trivial tasks. He is mostly known in the community for his open source software security research and strong progressive positions on providing tools and frameworks that are secure by default. @CiPHPerCoder


Need Technology Consultants?

Will tomorrow bring costly and embarrassing data breaches? Or will it bring growth, success, and peace of mind?

Our team of technology consultants have extensive knowledge and experience with application security and web/application development.

We specialize in cryptography and secure PHP development.

Let's Work Together Towards Success

Our Security Newsletters

Want the latest from Paragon Initiative Enterprises delivered straight to your inbox? We have two newsletters to choose from.

The first mails quarterly and often showcases our behind-the-scenes projects.

The other is unscheduled and gives you a direct feed into the findings of our open source security research initiatives.

Quarterly Newsletter   Security Announcements