Completed
Pull Request — master (#32)
by Michael
07:31
created

OpensslKey::algo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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
    {
70 49
        // Store the key as what was supplied
71
        $this->_key = \base64_decode($key, true);
72
73 49
        // If key was not proper base64, bail out
74 8
        if ($this->_key === false) {
75
            throw new InvalidKeyException(InvalidKeyException::BASE64ENC);
76
        }
77
78 41
        // If key was to short, bail out
79 1
        if (Str::strlen($this->_key) < 32) {
80
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
81
        }
82
83 40
        // Store algo in object
84
        $this->_algo = $algo;
85
86 40
        // Store init vector in object
87 40
        $this->_ivr = $ivr;
88
    }
89
90
    /**
91
     * Generate the authentication key.
92
     *
93
     * @return string
94
     */
95
    public function authenticationKey(): string
96 37
    {
97
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_algo);
98 37
    }
99
100
    /**
101
     * Generate the encryption key.
102
     *
103
     * @return string
104
     */
105
    public function encryptionKey(): string
106
    {
107
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_algo);
108 38
    }
109
110 38
    /**
111
     * Derive a key with differing info string parameters.
112
     *
113
     * @param string $info Info parameter to provide to hash_hkdf
114
     *
115
     * @return string
116
     */
117
    public function deriveKey(string $info): string
118
    {
119
        return \hash_hkdf($this->_algo, $this->_key, 0, $info, $this->_ivr);
120 40
    }
121
122 40
    /**
123
     * Calculates a given message HMAC.
124
     *
125
     * @param string $message
126
     * @return string
127
     */
128
    public function messageChecksum(string $message): string
129
    {
130
        return \hash_hmac($this->_algo, $message, $this->authenticationKey(), true);
131
    }
132
133
    /**
134 31
     * Returns the iv that object was created with.
135
     *
136 31
     * @return string
137 1
     */
138
    public function iv(): string
139
    {
140 31
        return $this->_ivr;
141
    }
142
143
    /**
144
     * Returns the cipher algo that object was created with.
145
     *
146
     * @return string
147
     */
148
    public function algo(): string
149
    {
150
        return $this->_algo;
151
    }
152
153
    /**
154
     * Generate a new key that meets requirements for dcrypt.
155
     *
156
     * @param int $bytes Size of key in bytes
157
     *
158
     * @return string
159
     * @throws InvalidKeyException
160
     */
161
    public static function create(int $bytes = 32): string
162
    {
163
        if ($bytes < 32) {
164
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
165
        }
166
167
        return \base64_encode(\random_bytes($bytes));
168
    }
169
}
170