Completed
Pull Request — master (#33)
by Michael
01:16
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\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
    private $_iv;
37
    private $_key;
38
    private $_algo;
39
    private $_cipher;
40
41
    /**
42
     * OpensslKey constructor.
43
     *
44
     * @param string $key    Key to use for encryption
45
     * @param string $algo   Algo to use for HKDF
46
     * @param string $cipher Name of cipher
47
     * @param string $iv     Initialization vector
48
     *
49
     * @throws InvalidKeyLengthException
50
     * @throws InvalidKeyEncodingException
51
     */
52 49
    public function __construct(
53
        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...
54
        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...
55
        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...
56
        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...
57
    ) {
58
        // Store args into the object
59 49
        [$this->_key, $this->_algo, $this->_cipher, $this->_iv] = func_get_args();
60
61
        // Attempt to base64 decode the key
62 49
        $this->_key = base64_decode($this->_key, true);
63
64
        // If key was not proper base64, bail out
65 49
        if ($this->_key === false) {
66 9
            throw new InvalidKeyEncodingException();
67
        }
68
69
        // If key was to short, bail out
70 40
        if (Str::length($this->_key) < 32) {
71
            throw new InvalidKeyLengthException();
72
        }
73 40
    }
74
75
    /**
76
     * Generate the authentication key.
77
     *
78
     * @return string
79
     */
80 37
    public function authenticationKey(): string
81
    {
82 37
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_cipher);
83
    }
84
85
    /**
86
     * Generate the encryption key.
87
     *
88
     * @return string
89
     */
90 38
    public function encryptionKey(): string
91
    {
92 38
        return $this->deriveKey(__FUNCTION__ . '|' . $this->_cipher);
93
    }
94
95
    /**
96
     * Derive a key with differing info string parameters.
97
     *
98
     * @param string $info Info parameter to provide to hash_hkdf
99
     *
100
     * @return string
101
     */
102 40
    public function deriveKey(string $info): string
103
    {
104 40
        return hash_hkdf($this->_algo, $this->_key, 0, $info, $this->_iv);
105
    }
106
107
    /**
108
     * Calculates a given message HMAC.
109
     *
110
     * @param string $message
111
     *
112
     * @return string
113
     */
114 37
    public function messageChecksum(string $message): string
115
    {
116 37
        return hash_hmac($this->_algo, $message, $this->authenticationKey(), true);
117
    }
118
119
    /**
120
     * Allows read only access to the internal variables needed by the openssl wrapper.
121
     *
122
     * @return array
123
     */
124 38
    public function wrapperVariables(): array
125
    {
126
        return [
127 38
            $this->_iv,
128 38
            $this->encryptionKey(),
129 37
            $this->_cipher,
130
        ];
131
    }
132
133
    /**
134
     * Generate a new key.
135
     *
136
     * @param int $bytes Size of key in bytes
137
     *
138
     * @throws Exception
139
     * @throws InvalidKeyLengthException
140
     *
141
     * @return string
142
     */
143 32
    public static function create(int $bytes = 32): string
144
    {
145 32
        if ($bytes < 32) {
146 1
            throw new InvalidKeyLengthException();
147
        }
148
149 32
        return base64_encode(random_bytes($bytes));
150
    }
151
}
152