Completed
Push — master ( a513ed...5cfd5a )
by Michael
01:14
created

OpensslKey::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 4
cts 4
cp 1
cc 2
nc 2
nop 1
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
        // Store the key as what was supplied
70 49
        $this->_key = \base64_decode($key);
71
72 49
        if ($this->_key === false) {
73
            throw new InvalidKeyException(InvalidKeyException::BASE64ENC);
74
        }
75
76 49
        if (Str::strlen($this->_key) < 32) {
77 9
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
78
        }
79
80
        // Store algo in object
81 40
        $this->_algo = $algo;
82
83
        // Store init vector in object
84 40
        $this->_ivr = $ivr;
85 40
    }
86
87
    /**
88
     * Generate the authentication key.
89
     *
90
     * @param string $info The extra info parameter for hash_hkdf
91
     *
92
     * @return string
93
     */
94 37
    public function authenticationKey(string $info): string
95
    {
96 37
        return $this->deriveKey(__FUNCTION__ . '|' . $info);
97
    }
98
99
    /**
100
     * Generate the encryption key.
101
     *
102
     * @param string $info The extra info parameter for hash_hkdf
103
     *
104
     * @return string
105
     */
106 38
    public function encryptionKey(string $info): string
107
    {
108 38
        return $this->deriveKey(__FUNCTION__ . '|' . $info);
109
    }
110
111
    /**
112
     * Derive a key with differing info string parameters.
113
     *
114
     * @param string $info Info parameter to provide to hash_hkdf
115
     *
116
     * @return string
117
     */
118 40
    public function deriveKey(string $info): string
119
    {
120 40
        return \hash_hkdf($this->_algo, $this->_key, 0, $info, $this->_ivr);
121
    }
122
123
    /**
124
     * Generate a new key that meets requirements for dcrypt.
125
     *
126
     * @param int $bytes Size of key in bytes
127
     *
128
     * @throws InvalidKeyException
129
     *
130
     * @return string
131
     */
132 31
    public static function create(int $bytes = 32): string
133
    {
134 31
        if ($bytes < 32) {
135 1
            throw new InvalidKeyException(InvalidKeyException::KEYLENGTH);
136
        }
137
138 31
        return \base64_encode(\random_bytes($bytes));
139
    }
140
}
141