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

OpensslKey   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 95.83%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 3
dl 0
loc 115
ccs 23
cts 24
cp 0.9583
rs 10
c 0
b 0
f 0

7 Methods

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