Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
SecretBox
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
6 / 6
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 validatedLengths
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
 encrypt
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 decrypt
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 makeKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 makeNonce
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework Crypto Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\Crypto;
11
12use Exception;
13use LengthException;
14use SensitiveParameter;
15use SodiumException;
16
17/**
18 * Class SecretBox.
19 *
20 * @package crypto
21 */
22class SecretBox
23{
24    protected string $key;
25    protected string $nonce;
26
27    /**
28     * SecretBox constructor.
29     *
30     * @param string $key
31     * @param string $nonce
32     *
33     * @see SecretBox::makeKey()
34     * @see SecretBox::makeNonce()
35     *
36     * @throws LengthException if key or nonce has not the required length
37     */
38    public function __construct(
39        #[SensitiveParameter] string $key,
40        #[SensitiveParameter] string $nonce
41    ) {
42        $this->validatedLengths($key, $nonce);
43        $this->key = $key;
44        $this->nonce = $nonce;
45    }
46
47    /**
48     * Validates key and nonce.
49     *
50     * @param string $key
51     * @param string $nonce
52     *
53     * @throws LengthException if key or nonce has not the required length
54     */
55    protected function validatedLengths(
56        #[SensitiveParameter] string $key,
57        #[SensitiveParameter] string $nonce
58    ) : void {
59        $length = \mb_strlen($key, '8bit');
60        if ($length !== \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
61            throw new LengthException(
62                'SecretBox key has not the required length (32 bytes), '
63                . $length . ' given'
64            );
65        }
66        $length = \mb_strlen($nonce, '8bit');
67        if ($length !== \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES) {
68            throw new LengthException(
69                'SecretBox nonce has not the required length (24 bytes), '
70                . $length . ' given'
71            );
72        }
73    }
74
75    /**
76     * Encrypts a secret box message.
77     *
78     * @param string $message
79     *
80     * @throws SodiumException
81     *
82     * @return string
83     */
84    public function encrypt(#[SensitiveParameter] string $message) : string
85    {
86        return \sodium_crypto_secretbox($message, $this->nonce, $this->key);
87    }
88
89    /**
90     * Decrypts a secret box message ciphertext.
91     *
92     * @param string $ciphertext
93     *
94     * @throws SodiumException
95     *
96     * @return false|string
97     */
98    public function decrypt(#[SensitiveParameter] string $ciphertext) : false | string
99    {
100        return \sodium_crypto_secretbox_open($ciphertext, $this->nonce, $this->key);
101    }
102
103    /**
104     * Makes a secret box key.
105     *
106     * @return string
107     */
108    public static function makeKey() : string
109    {
110        return \sodium_crypto_secretbox_keygen();
111    }
112
113    /**
114     * Makes a secret box nonce with the correct length.
115     *
116     * @throws Exception if fail to get random bytes
117     *
118     * @return string
119     */
120    public static function makeNonce() : string
121    {
122        return \random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
123    }
124}