Completed
Pull Request — master (#33)
by Michael
01:09
created

OpensslKey::deriveKey()   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 1
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\InvalidKeyEncodingException;
21
use Dcrypt\Exceptions\InvalidKeyLengthException;
22
use Exception;
23
24
/**
25
 * Provides key derivation functions.
26
 *
27
 * @category Dcrypt
28
 *
29
 * @author   Michael Meyer (mmeyer2k) <[email protected]>
30
 * @license  http://opensource.org/licenses/MIT The MIT License (MIT)
31
 *
32
 * @link     https://github.com/mmeyer2k/dcrypt
33
 */
34
final class OpensslKey
35
{
36
    /**
37
     * @var string
38
     */
39
    private $_iv;
40
41
    /**
42
     * @var false|string
43
     */
44
    private $_key;
45
46
    /**
47
     * @var string
48
     */
49
    private $_algo;
50
51
    /**
52
     * @var string
53
     */
54
    private $_cipher;
55
56
    /**
57
     * OpensslKey constructor.
58
     *
59
     * @param string $key    Key to use for encryption
60
     * @param string $algo   Algo to use for HKDF
61
     * @param string $cipher Name of cipher
62
     * @param string $iv     Initialization vector
63
     *
64
     * @throws InvalidKeyLengthException
65
     * @throws InvalidKeyEncodingException
66
     */
67 49
    public function __construct(
68
        string $key,
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
69
        string $algo,
0 ignored issues
show
Unused Code introduced by
The parameter $algo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
70
        string $cipher,
0 ignored issues
show
Unused Code introduced by
The parameter $cipher is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
71
        string $iv
0 ignored issues
show
Unused Code introduced by
The parameter $iv is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
    ) {
73
        // Store args into the object
74 49
        [$this->_key, $this->_algo, $this->_cipher, $this->_iv] = func_get_args();
75
76
        // Attempt to base64 decode the key
77 49
        $this->_key = base64_decode($this->_key, true);
78
79
        // If key was not proper base64, bail out
80 49
        if ($this->_key === false) {
81 9
            throw new InvalidKeyEncodingException();
82
        }
83
84
        // If key was to short, bail out
85 40
        if (Str::length($this->_key) < 32) {
86
            throw new InvalidKeyLengthException();
87
        }
88 40
    }
89
90
    /**
91
     * Generate the authentication key.
92
     *
93
     * @return string
94
     */
95 37
    public function authenticationKey(): string
96
    {
97 37
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_cipher);
98
    }
99
100
    /**
101
     * Generate the encryption key.
102
     *
103
     * @return string
104
     */
105 38
    public function encryptionKey(): string
106
    {
107 38
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_cipher);
108
    }
109
110
    /**
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 40
    public function deriveKey(string $info): string
118
    {
119 40
        return hash_hkdf($this->_algo, $this->_key, 0, $info, $this->_iv);
120
    }
121
122
    /**
123
     * Calculates a given message HMAC.
124
     *
125
     * @param string $message
126
     *
127
     * @return string
128
     */
129 37
    public function messageChecksum(string $message): string
130
    {
131 37
        return hash_hmac($this->_algo, $message, $this->authenticationKey(), true);
132
    }
133
134
    /**
135
     * Allows read only access to the internal variables needed by the openssl wrapper.
136
     *
137
     * @return array
138
     */
139 38
    public function wrapperVariables(): array
140
    {
141
        return [
142 38
            $this->_iv,
143 38
            $this->encryptionKey(),
144 37
            $this->_cipher,
145
        ];
146
    }
147
148
    /**
149
     * Generate a new key.
150
     *
151
     * @param int $bytes Size of key in bytes
152
     *
153
     * @throws Exception
154
     * @throws InvalidKeyLengthException
155
     *
156
     * @return string
157
     */
158 32
    public static function create(int $bytes = 32): string
159
    {
160 32
        if ($bytes < 32) {
161 1
            throw new InvalidKeyLengthException();
162
        }
163
164 32
        return base64_encode(random_bytes($bytes));
165
    }
166
}
167