Completed
Push — master ( 88d3db...887de8 )
by Michael
01:27
created

OpensslKey::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 9
cts 9
cp 1
rs 9.536
c 0
b 0
f 0
cc 3
nc 3
nop 3
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * OpensslKey.php.
7
 *
8
 * PHP version 7
9
 *
10
 * @category Dcrypt
11
 *
12
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
13
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
14
 *
15
 * @link     https://github.com/mmeyer2k/dcrypt
16
 */
17
18
namespace Dcrypt;
19
20
use Dcrypt\Exceptions\InvalidKeyException;
21
22
/**
23
 * Provides key derivation functions.
24
 *
25
 * @category Dcrypt
26
 *
27
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
28
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
29
 *
30
 * @link     https://github.com/mmeyer2k/dcrypt
31
 */
32
final class OpensslKey
33
{
34
    /**
35
     * High entropy key.
36
     *
37
     * @var string
38
     */
39
    private $_key;
40
41
    /**
42
     * Algo string.
43
     *
44
     * @var string
45
     */
46
    private $_algo;
47
48
    /**
49
     * High entropy salt.
50
     *
51
     * @var string
52
     */
53
    private $_ivr;
54
55
    /**
56
     * OpensslKey constructor.
57
     *
58
     * @param string $algo Algo to use for HKDF
59
     * @param string $key  Key to use for encryption
60
     * @param string $ivr  Initialization vector
61
     *
62
     * @throws InvalidKeyException
63
     */
64 49
    public function __construct(
65
        string $algo,
66
        string $key,
67
        string $ivr = ''
68
    ) {
69
        // Store the key as what was supplied
70 49
        $this->_key = \base64_decode($key, true);
71
72
        // If key was not proper base64, bail out
73 49
        if ($this->_key === false) {
74 8
            throw new InvalidKeyException(InvalidKeyException::BASE64ENC);
75
        }
76
77
        // If key was to short, bail out
78 41
        if (Str::strlen($this->_key) < 32) {
79 1
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
80
        }
81
82
        // Store algo in object
83 40
        $this->_algo = $algo;
84
85
        // Store init vector in object
86 40
        $this->_ivr = $ivr;
87 40
    }
88
89
    /**
90
     * Generate the authentication key.
91
     *
92
     * @param string $info The extra info parameter for hash_hkdf
93
     *
94
     * @return string
95
     */
96 37
    public function authenticationKey(string $info): string
97
    {
98 37
        return $this->deriveKey(__FUNCTION__ . '|' . $info);
99
    }
100
101
    /**
102
     * Generate the encryption key.
103
     *
104
     * @param string $info The extra info parameter for hash_hkdf
105
     *
106
     * @return string
107
     */
108 38
    public function encryptionKey(string $info): string
109
    {
110 38
        return $this->deriveKey(__FUNCTION__ . '|' . $info);
111
    }
112
113
    /**
114
     * Derive a key with differing info string parameters.
115
     *
116
     * @param string $info Info parameter to provide to hash_hkdf
117
     *
118
     * @return string
119
     */
120 40
    public function deriveKey(string $info): string
121
    {
122 40
        return \hash_hkdf($this->_algo, $this->_key, 0, $info, $this->_ivr);
123
    }
124
125
    /**
126
     * Generate a new key that meets requirements for dcrypt.
127
     *
128
     * @param int $bytes Size of key in bytes
129
     *
130
     * @throws InvalidKeyException
131
     *
132
     * @return string
133
     */
134 31
    public static function create(int $bytes = 32): string
135
    {
136 31
        if ($bytes < 32) {
137 1
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
138
        }
139
140 31
        return \base64_encode(\random_bytes($bytes));
141
    }
142
}
143