php sodium что это
Modern PHP data Encryption/Decryption with Sodium extension
Throughout the years PHP has added support for several extensions, libraries, and algorithms to encrypt and decrypt data. With several libraries and extensions with various levels of maintenance, several algorithms each potentially carrying pros and cons, some even inherently being insecure, it is very difficult to select the appropriate PHP extension, library, encryption constructs, and balance the security and performance.
mcrypt is one of the oldest PHP extensions to bring encryption/decryption capabilities to PHP. It is no longer maintained, and PHP un-bundled it in PHP 7.2.
OpenSSL is another library that is more widely adopted, and is actively supported. OpenSSL offers a wide range of cipher, key exchange, and authentication algorithms, and some most of them can be insecure if used at the wrong use use-case. For example, the most common encryption algorithm OpenSSL offers is AES (Advanced Encryption Standard ) has several operations modes and key sizes that leaves rooms for insecure uses of it. From the outset, AES modes such as ECB (Electronic codebook) are not semantically secure, and some modes such as CBC (Cipher block chaining) require authenticating the encrypted messages to be completely secure, and still could be vulnerable to padding oracle attacks, such as POODLE.
Libsodium, a fork of NaCl is a more modern and heavily opinionated cryptography library. It offers secure and sensible defaults, and takes away a lot of decision making from the end user to library maintainers. PHP. Libsodium is available as a PECL extension, but PHP also includes the extension in PHP core since PHP 7.2.
Installing/Enabling Sodium Extension
Alternately, it is possible to list the PHP extensions in PHP CLI, and inspect the output:
The following example should work most of the standard PHP setups:
Symmetric and Asymmetric Encryption
With symmetric encryption and decryption, the same key is used to encrypt and decrypt. In real-life, this is similar to using a door lock that locks and unlocks a door using the key.
If a message is encrypted and decrypted on the same device, symmetric encryption is more appropriate. Some example use case on using symmetric encryption:
Asymmetric encryption involves a pair of keys: A public key and its private key.
The asymmetry here is that the messages are encrypted with the public key, and it can only be decrypted with the private key. As the name suggests, the public can be freely and public distributed. When the key pair is generated, it is generated in a way that it is mathematically possible for the private key — and private key alone — to decrypt a message encrypted with the public key.
This asymmetry makes it possible to share the public key with any interested party, and have them send encrypted messages that nobody else can read without the private key.
Some of the use cases for asymmetric use cases include:
Symmetric Encryption/Decryption with Sodium
PHP Sodium extension provides a few algorithms with optimal defaults and opinionated key sizes to encrypt/decrypt data using a key.
All of the algorithms provided by Sodium extension provide authenticated encryption, which means that the encrypted text will be authenticated against tampering. This prevents Chosen-ciphertext attacks. With approaches such as mcrypt or most ciphers from OpenSSL, it is up to the caller to generate an HMAC/signature and protect against such attacks.
Applications that need to store the authentication tag (MAC) and encrypted text may do so by using the «detached» API variants provided Sodium.
At the moment, Sodium provides four ciphers to choose from:
All of the four ciphers provide authentication by default, are safe to be used. Choosing the appropriate cipher is a balance between compatibility with other libraries and programming languages and tooling.
AES256-GCM is widely supported in most CPUs (AES-NI instructions set), and is supported in other extensions such as OpenSSL.
XChaCha20 with Poly1305 MAC
Sodium extension provides functions to easily generate a key, encrypt, and decrypt a message. In addition, the random_bytes function comes in handy to generate a random nonce value.
Create a Secret Key
The secret key for symmetric encryption is generated using a Cryptographically-secure pseudorandom number generator.
Sodium provides an easy function to generate the key with required length:
This key must be securely stored, and will be used to decrypt messages as well.
Generate Nonce Values
To prevent replay attacks, each encrypted message must be different even if the source data is same. This is achieved by generating a random value called nonce. This value is used once, and generated for each encrypted message.
XChaCha20-Poly1305 cipher requires a nonce length of 192 bits, and is made easier with the built-in constant :
Encrypting a Message
Storing/Transmitting the Encrypted Message
Once the encrypted text is generated, it contains the authentication tag, which should prevent unexpected and malicious tampering of the encrypted text.
Additionally, sodium_crypto_aead_xchacha20poly1305_ietf_encrypt function returns a byte stream. It cannot be directly printed (on a web page or a JSON response for example), and must be converted to a text format using functions such as base64_encode or bin2hex prior to printing or transmitting to a medium that cannot handle raw byte streams.
Decrypting a Message
Complete Example: Authenticated Symmetric Encryption/Decryption
Migrating from Mcrypt and OpenSSL
mcrypt and OpenSSL extensions also provide symmetric encryption. However, they have varying levels of support for authentication, key lengths, and nonce lengths.
Generally speaking, the sodium_crypto_aead_xchacha20poly1305_ietf_* functions are better alternatives to mcrypt_encrypt and openssl_encrypt functions.
Authenticated Asymmetric Encryption/Decryption with Sodium
Sodium also provides a way to asymmetrically encrypt and decrypt messages.
Asymmetric encryption involves two parties. Both parties create a key pair, containing a private key and a public key. The public key is distributed to other parties that need to communicate with.
For example, if Alice and Bob want to communicate securely, and must ensure that:
Sodium extension provides a Crypto Box API that fulfills the authenticity and privacy of such messages. Prior to sending messages, Alice and Bob (or all parties involved) must generate a key pair, and securely exchange the public key.
Sodium also provides secure key exchange protocols, but it is not covered by this article.
When a message is sent, the sender encrypts it with recipient’s public key, and signs it with the sender’s private key. Once the message is transmitted, the recipient authenticates the messages with the sender’s public key, and decrypts with the recipient’s private key.
If the recipient does not need to authenticate the received messages — make sure that the message was indeed sent by the sender — Sodium extension also Unauthenticated Asymmetric Encryption/Decryption using crypto_box_seal API.
Generate Key Pairs
All parties that need to communicate must generate a key pair. The secret must be kept private, as it is used to sign and decrypt messages.
Individually on both Alice’s and Bob’s devices
Exchange Keys
For authenticated asymmetric encryption and decryption, both parties involved must exchange their public keys securely. This can be done using a key-exchange protocol, or transmitting the keys using another secure channel, such as an HTTPS request.
Sodium provides key-exchange functionality with its sodium_crypto_kx_* functions. However, this article does not cover those APIs at this point ensure the brevity of it.
After a successful exchange keys:
Create Nonce Values
Similar to creating a nonce value for each message with symmetric encryption, an authenticated asymmetric message must use a nonce value as well.
Build the Encryption Key Pair
Before encrypting a message, the sender (Alice in this example) must create a new key pair, containing the recipient’s public key and sender’s private key. This can be done by concatenating the public key and private key, or using the sodium_crypto_box_keypair_from_secretkey_and_publickey function.
Sender:
Encrypt and Sign a Message
With the keys exchanged, nonce generated, and encryption key pair built, it’s now time to encrypt a message.
Storing/Transmitting the Encrypted and Signed Text
Once the message is encrypted and signed, only the recipient can with the private key can decrypt the message. Anyone with the sender’s public key can authenticate the message, but not read the contents without the recipient’s private key.
Decrypting and Authenticating a Received Message
The recipient can authenticate a message and make sure it is signed by the sender if the recipient has the public key of the sender (public key of Alice in this example).
sodium_crypto_box_keypair_from_secretkey_and_publickey function is used again to create a new key pair, but this time, it is created from the recipient’s private key, and the sender’s public key.
Once the key pair is generated, it is possible to authenticate and decrypt a message.
sodium_crypto_box_open function authenticates that the message is signed by the sender (signed using sender’s private key), and decrypts the message using recipient’s private key.
Complete Example: Authenticated Public Key Encryption/Decryption
Unauthenticated Asymmetric Encryption/Decryption with Sodium
If the recipient does not need to authenticate the incoming messages, but only decrypt them, it might be a use case Sodium’s crypto_box_seal API.
crypto_box_seal in Sodium
Sodium’s crypto_box_seal functions are used to encrypt and decrypt a message using a pair of public and private keys. The major difference between Authenticated Asymmetric Encryption/Decryption is that crypto_box_seal does not authenticate the messages.
The recipient can decrypt any messaged encrypted with its public key, but has no way to identify or authenticate the sender’s identity.
Create a Key Pair for Recipient
With unauthenticated asymmetric encryption, only the recipient is required to generate a key pair:
Distribute Public Key
The easiest and most common way to distribute a public key is over an HTTPS connection. For example, senders can download the public key of the sender from recipient’s web site served over HTTPS.
Note that although anonymous asymmetric encryption does not provide authentication for messages, the public key must be transmitted securely, and the sender must validate the recipient’s public key corresponds with the actual recipient, and the key is not tampered during transmission.
Encrypt a Message
With the recipient’s public key, any sender can encrypt a message:
Store/Transmit Messages
Encrypted messages can only be opened by the recipient holding the private key. However, because there is no there is no authentication or nonce values involved, this is prone to replay attacks.
Decrypt Messages
To decrypt a message encrypted with a public key, the recipient must possess the corresponding private key.
sodium_crypto_box_seal_open decrypts an encrypted message using the secret key.
PHP Encryption with Libsodium
What Is Libsodium?
Libsodium, also known as Sodium, is a powerful cryptography library. It is a portable, cross-compilable, installable, and packageable fork of NaCl, a famous cryptographic tool designed by Prof. D.J. Bernstein. If you need to enable PHP encryption/decryption, you can use Libsodium.
What Algorithms Are in Libsodium?
The Libsodium library is an “opinionated” cryptography library. This means the algorithms in Sodium have been selected and cannot be changed.
The library uses some of the most robust algorithms available, including:
If you need to use different algorithms — for instance, if you need to ensure compatibility with existing cryptosystems — you need to look for a different library, such as OpenSSL.
Libsodium Is Designed to Prevent Side-Channel Attacks
Apart from the selection of the best algorithms available, Sodium, and NaCl, were designed to prevent side-channel attacks. This is a very good point for security because the majority of attacks are based on issues in the implementations, rather than weaknesses in the algorithm itself.
Just to give you an idea, one of the most successful side-channel attacks in history was performed by Adi Shamir, Eran Tromer, and Dag Arne Osvik in 2006. The attack was aimed to discover, in **65 milliseconds,** the secret key used in widely deployed software for hard-disk encryption. (Here is the extended article.)
PHP Encryption With Libsodium
Developers can use Sodium for PHP encryption and decryption with PHP 7.2 and newer without an extension. If you want to use Sodium with PHP 7.0 or 7.1, you need to install a PECL extension.
Libsodium vs. OpenSSL
When comparing Libsodium vs. OpenSSL with the chart below, you can see that there are many differences between the two cryptographic libraries.
Libsodium | OpenSSL | |
---|---|---|
Development Language | C | C |
Software License | ISC License | Apache License, BSD License |
Last Updated | December, 2017 | March, 2020 |
Code Size | 44 kSLOC | 472 kSLOC |
Key Generation/Exchange | ECDH | ECDH, DH, DSA, RSA |
Elliptic Curve Cryptography | NIST | NIST, SECG, ECC Brainpool, ECDSA, ECDH, Curve25519, EdDSA, GOST R 34.10 |
Public Key Cryptography Standards | n/a | PKCS#1, PKCS#5, PKCS#8, PKCS#12, ASN.1 |
Hash Functions | SHA-2 | MD5, SHA-1, SHA-2, SHA-3, RIPEMD-160, Tiger, Whirlpool, GOST, BLAKE2 |
MAC Algorithms | HMAC-SHA2, Poly1305-AES, BLAKE2-MAC | HMAC-MD5, HMAC-SHA1, HMAC-SHA2, Poly1305-AES |
Block Cipher Algorithms | AES | AES, Camellia, 3DES, Blowfish, CAST5, IDEA, GOST 28147-89/GOST R 34.12-2015 ARIA |
Cipher Modes | CTR, GCM | ECB, CBC, OFB, CFB, CTR, CCM, GCM, OCB, XTS, AES-Wrap, Stream |
Stream Ciphers | Salsa20, ChaCha | RC4, ChaCha |
Libsodium Examples
Here are six examples for using the Sodium cryptography library:
Libsodium PHP String Encrypt Example
The Sodium APIs are quite simple to use. Just to give you an idea, here’s example code on how to encrypt a PHP string with a shared-key:
And here how to authenticate a message (without encryption):
To see more PHP code examples, see the slides from this ZendCon and OpenEnterprise presentation.
Want to learn how Zend by Perforce can help you with your security strategy?
Предопределённые константы
Перечисленные ниже константы определены данным модулем и могут быть доступны только в том случае, если PHP был собран с поддержкой этого модуля или же в том случае, если данный модуль был динамически загружен во время выполнения.
SODIUM_LIBRARY_VERSION ( string ) SODIUM_LIBRARY_MAJOR_VERSION ( int ) SODIUM_LIBRARY_MINOR_VERSION ( int ) SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES ( int ) SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES ( int ) SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES ( int ) SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES ( int ) SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES ( int ) SODIUM_CRYPTO_AUTH_BYTES ( int ) SODIUM_CRYPTO_AUTH_KEYBYTES ( int ) SODIUM_CRYPTO_BOX_SEALBYTES ( int ) SODIUM_CRYPTO_BOX_SECRETKEYBYTES ( int ) SODIUM_CRYPTO_BOX_PUBLICKEYBYTES ( int ) SODIUM_CRYPTO_BOX_KEYPAIRBYTES ( int ) SODIUM_CRYPTO_BOX_MACBYTES ( int ) SODIUM_CRYPTO_BOX_NONCEBYTES ( int ) SODIUM_CRYPTO_BOX_SEEDBYTES ( int ) SODIUM_CRYPTO_KDF_BYTES_MIN ( int ) SODIUM_CRYPTO_KDF_BYTES_MAX ( int ) SODIUM_CRYPTO_KDF_CONTEXTBYTES ( int ) SODIUM_CRYPTO_KDF_KEYBYTES ( int ) SODIUM_CRYPTO_KX_SEEDBYTES ( int ) SODIUM_CRYPTO_KX_SESSIONKEYBYTES ( int ) SODIUM_CRYPTO_KX_PUBLICKEYBYTES ( int ) SODIUM_CRYPTO_KX_SECRETKEYBYTES ( int ) SODIUM_CRYPTO_KX_KEYPAIRBYTES ( int ) SODIUM_CRYPTO_GENERICHASH_BYTES ( int ) SODIUM_CRYPTO_GENERICHASH_BYTES_MIN ( int ) SODIUM_CRYPTO_GENERICHASH_BYTES_MAX ( int ) SODIUM_CRYPTO_GENERICHASH_KEYBYTES ( int ) SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN ( int ) SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX ( int ) SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 ( int ) SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 ( int ) SODIUM_CRYPTO_PWHASH_ALG_DEFAULT ( int ) SODIUM_CRYPTO_PWHASH_SALTBYTES ( int ) SODIUM_CRYPTO_PWHASH_STRPREFIX ( string ) SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE ( int ) SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE ( int ) SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE ( int ) SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE ( int ) SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE ( int ) SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE ( int ) SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES ( int ) SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX ( string ) SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE ( int ) SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE ( int ) SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE ( int ) SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE ( int ) SODIUM_CRYPTO_SCALARMULT_BYTES ( int ) SODIUM_CRYPTO_SCALARMULT_SCALARBYTES ( int ) SODIUM_CRYPTO_SHORTHASH_BYTES ( int ) SODIUM_CRYPTO_SHORTHASH_KEYBYTES ( int ) SODIUM_CRYPTO_SECRETBOX_KEYBYTES ( int ) SODIUM_CRYPTO_SECRETBOX_MACBYTES ( int ) SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ( int ) SODIUM_CRYPTO_SIGN_BYTES ( int ) SODIUM_CRYPTO_SIGN_SEEDBYTES ( int ) SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES ( int ) SODIUM_CRYPTO_SIGN_SECRETKEYBYTES ( int ) SODIUM_CRYPTO_SIGN_KEYPAIRBYTES ( int ) SODIUM_CRYPTO_STREAM_NONCEBYTES ( int ) SODIUM_CRYPTO_STREAM_KEYBYTES ( int )
Php sodium что это
A simple, low-level PHP extension for libsodium.
Requires libsodium >= 1.0.9 and PHP 7.<0,1,2,3,4>.x or PHP 8.0.x
Full documentation here: Using Libsodium in PHP Projects, a guide to using the libsodium PHP extension for modern, secure, and fast cryptography.
libsodium (and, if you are using binary packages, on some distributions, libsodium-dev as well) has to be installed before this extension.
Then, use the PHP extension manager:
On some Linux distributions such as Debian, you may have to install PECL ( php-pear ), the PHP development package ( php-dev ) and a compiler ( build-essential ) prior to running this command.
libsodium-php 1.x compatibility API for libsodium-php 2.x
For projects using the 1.x API, or willing to use it, a compatibility layer is available.
Polyfill Libsodium brings the \Sodium\ namespace back.
Encrypt a single message using a secret key
$secret_key is a secret key. Not a password. It’s binary data, not something designed to be human readable, but rather to have a key space as large as possible for a given length. The keygen() function creates such a key. That has to remain secret, as it is used both to encrypt and decrypt data.
$nonce is a unique value. Like the secret, its length is fixed. But it doesn’t have to be secret, and can be sent along with the encrypted message. The nonce doesn’t have to be unpredictable either. It just has to be unique for a given key. With the secretbox() API, using random_bytes() is a totally fine way to generate nonces.
Encrypted messages are slightly larger than unencrypted messages, because they include an authenticator, used by the decryption function to check that the content was not altered.
Encrypt a single message using a secret key, and hide its length
Sometimes, the length of a message may provide a lot of information about its nature. If a message is one of «yes», «no» and «maybe», encrypting the message doesn’t help: knowing the length is enough to know what the message is.
Padding is a technique to mitigate this, by making the length a multiple of a given block size.
Messages must be padded prior to encryption, and unpadded after decryption.
Encrypt a file using a secret key
There’s a little bit more code than in the previous examples.
In fact, crypto_secretbox() would work to encrypt as file, but only if that file is pretty small. Since we have to provide the entire content as a string, it has to fit in memory.
If the file is large, we can split it into small chunks, and encrypt chunks individually.
By doing do, we can encrypt arbitrary large files. But we need to make sure that chunks cannot be deleted, truncated, duplicated and reordered. In other words, we don’t have a single «message», but a stream of messages, and during the decryption process, we need a way to check that the whole stream matches what we encrypted.
Encrypt a file using a key derived from a password:
Read the stored parameters and decrypt the file:
A password cannot be directly used as a secret key. Passwords are short, must be typable on a keyboard, and people who don’t use a password manager should be able to remember them.
A 8 characters password is thus way weaker than a 8 bytes key.
The sodium_crypto_pwhash() function perform a computationally intensive operation on a password in order to derive a secret key.
By doing do, brute-forcing all possible passwords in order to find the secret key used to encrypt the data becomes an expensive operation.
Multiple algorithms can be used to derive a key from a password, and for each of them, different parameters can be chosen. It is important to store all of these along with encrypted data. Using the same algorithm and the same parameters, the same secret key can be deterministically recomputed.