Completed
Pull Request — master (#32)
by Michael
01:37
created

OpensslKey::iv()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
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 $_iv;
54
55
    /**
56
     * Name of cipher
57
     *
58
     * @var string
59
     */
60
    private $_cipher;
61
62
    /**
63
     * OpensslKey constructor.
64
     *
65
     * @param string $key Key to use for encryption
66
     * @param string $algo Algo to use for HKDF
67
     * @param string $cipher Name of cipher
68
     * @param string $ivr Initialization vector
69
     *
70
     * @throws InvalidKeyException
71
     */
72 48
    public function __construct(
73
        string $key,
74
        string $algo,
75
        string $cipher = '',
76
        string $ivr = ''
77
    )
78
    {
79
        // Store the key as what was supplied
80 48
        $this->_key = \base64_decode($key, true);
81
82
        // If key was not proper base64, bail out
83 48
        if ($this->_key === false) {
84 9
            throw new InvalidKeyException(InvalidKeyException::BASE64ENC);
85
        }
86
87
        // If key was to short, bail out
88 39
        if (Str::strlen($this->_key) < 32) {
89
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
90
        }
91
92
        // Store algo in object
93 39
        $this->_algo = $algo;
94
95
        // Store init vector in object
96 39
        $this->_iv = $ivr;
97
98
        // Store the cipher name
99 39
        $this->_cipher = $cipher;
100 39
    }
101
102
    /**
103
     * Generate the authentication key.
104
     *
105
     * @return string
106
     */
107 36
    public function authenticationKey(): string
108
    {
109 36
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_cipher);
110
    }
111
112
    /**
113
     * Generate the encryption key.
114
     *
115
     * @return string
116
     */
117 37
    public function encryptionKey(): string
118
    {
119 37
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_cipher);
120
    }
121
122
    /**
123
     * Derive a key with differing info string parameters.
124
     *
125
     * @param string $info Info parameter to provide to hash_hkdf
126
     *
127
     * @return string
128
     */
129 39
    public function deriveKey(string $info): string
130
    {
131 39
        return \hash_hkdf($this->_algo, $this->_key, 0, $info, $this->_iv);
132
    }
133
134
    /**
135
     * Calculates a given message HMAC.
136
     *
137
     * @param string $message
138
     * @return string
139
     */
140 36
    public function messageChecksum(string $message): string
141
    {
142 36
        return \hash_hmac($this->_algo, $message, $this->authenticationKey(), true);
143
    }
144
145
    /**
146
     * Returns the iv that object was created with.
147
     *
148
     * @return string
149
     */
150 37
    public function iv(): string
151
    {
152 37
        return $this->_iv;
153
    }
154
155
    /**
156
     * Returns the cipher name
157
     *
158
     * @return string
159
     */
160 36
    public function cipher(): string
161
    {
162 36
        return $this->_cipher;
163
    }
164
165
    /**
166
     * Returns the cipher algo that object was created with.
167
     *
168
     * @return string
169
     */
170
    public function algo(): string
171
    {
172
        return $this->_algo;
173
    }
174
175
    /**
176
     * Generate a new key that meets requirements for dcrypt.
177
     *
178
     * @param int $bytes Size of key in bytes
179
     *
180
     * @return string
181
     * @throws InvalidKeyException
182
     */
183 31
    public static function create(int $bytes = 32): string
184
    {
185 31
        if ($bytes < 32) {
186 1
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
187
        }
188
189 31
        return \base64_encode(\random_bytes($bytes));
190
    }
191
}
192