Encryptor::setCipherIvLen()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
namespace coossions\crypt;
3
4
use coossions\exceptions\OpenSSLException;
5
6
class Encryptor implements EncryptorInterface
7
{
8
    /** @var string $secret the secret user key */
9
    protected $secret = '';
10
11
    protected $expire       = 2592000; // 30 days
12
    protected $digestAlgo   = 'sha256';
13
    protected $cipherAlgo   = 'aes-256-ctr';
14
    protected $cipherIvLen  = 16; // aes-256-ctr length
15
    protected $digestLength = 32; // sha256 length for raw-data
16
17
    /**
18
     * Encryptor constructor.
19
     * @param string $secret the secret key to be used in openssl_digest
20
     */
21 7
    public function __construct(string $secret)
22
    {
23 7
        $this->secret = $secret;
24 7
    }
25
26
    /**
27
     * Compares 2 hashes
28
     * @param string $digest    Digest to compare with
29
     * @param string $message   Original message
30
     * @param string $sid       Session id
31
     * @return bool
32
     */
33 1
    private function hashesEqual(string $digest, string $message, string $sid): bool
34
    {
35 1
        return hash_equals(
36 1
            hash_hmac($this->digestAlgo, $sid . $message, $this->secret, true),
37 1
            $digest
38
        );
39
    }
40
41
    /**
42
     * Encrypt a string.
43
     *
44
     * @param  string $in String to encrypt.
45
     * @param  string $key Encryption key.
46
     *
47
     * @param string $sid
48
     * @return string The encrypted string.
49
     * @throws OpenSSLException
50
     */
51 2
    public function encryptString(string $in, string $key, string $sid): string
52
    {
53
        // Build an initialisation vector
54 2
        $iv = random_bytes($this->cipherIvLen);
55
        // Hash the key
56 2
        $keyHash   = openssl_digest($key, $this->digestAlgo, true);
57 2
        $encrypted = openssl_encrypt($in, $this->cipherAlgo, $keyHash, OPENSSL_RAW_DATA, $iv);
58 2
        if (false === $encrypted) {
59
            throw new OpenSSLException('encryptString() - Encryption failed: ' . openssl_error_string());
60
        }
61
        // The result comprises the IV and encrypted data
62 2
        $msg = $iv . $encrypted;
63 2
        $digest = hash_hmac($this->digestAlgo, $sid . $msg, $this->secret, true);
64
65 2
        return base64_encode($digest . $msg);
66
    }
67
68
    /**
69
     * Decrypt a string.
70
     *
71
     * @param  string $in  String to decrypt.
72
     * @param  string $key Decryption key.
73
     *
74
     * @param string  $sid Session id
75
     *
76
     * @return string The decrypted string.
77
     * @throws OpenSSLException
78
     */
79 1
    public function decryptString(string $in, string $key, string $sid): string
80
    {
81 1
        $raw = base64_decode($in);
82
83 1
        if (strlen($raw) < $this->cipherIvLen) {
84
            throw new OpenSSLException(
85
                'decryptString() - data length ' . strlen($raw) . ' is less than iv length ' . $this->cipherIvLen
86
            );
87
        }
88
89 1
        $digest = substr($raw, 0, $this->digestLength);
90 1
        if (false === $digest) {
91
            return '';
92
        }
93 1
        $msg = substr($raw, $this->digestLength);
94 1
        if (false === $msg) {
95
            return '';
96
        }
97
98 1
        if ($this->hashesEqual($digest, $msg, $sid) === false) {
99
            return '';
100
        }
101
102
        // Extract the initialisation vector and encrypted data
103 1
        $iv  = substr($msg, 0, $this->cipherIvLen);
104 1
        $raw = substr($msg, $this->cipherIvLen);
105
        // Hash the key
106 1
        $keyHash = openssl_digest($key, $this->digestAlgo, true);
107 1
        $res     = openssl_decrypt($raw, $this->cipherAlgo, $keyHash, OPENSSL_RAW_DATA, $iv);
108 1
        if (false === $res) {
109
            throw new OpenSSLException('decryptString - decryption failed: ' . openssl_error_string());
110
        }
111
112 1
        return $res;
113
    }
114
115
    /**
116
     * @param int $expire
117
     */
118 1
    public function setExpire($expire)
119
    {
120 1
        $this->expire = $expire;
121 1
    }
122
123
    /**
124
     * @return int
125
     */
126 3
    public function getExpire(): int
127
    {
128 3
        return $this->expire;
129
    }
130
131
    /**
132
     * @param string $digestAlgo
133
     */
134 2
    public function setDigestAlgo($digestAlgo)
135
    {
136 2
        $this->digestAlgo = $digestAlgo;
137 2
    }
138
139
    /**
140
     * @return string
141
     */
142 3
    public function getDigestAlgo(): string
143
    {
144 3
        return $this->digestAlgo;
145
    }
146
147
    /**
148
     * @param string $cipherAlgo
149
     */
150 2
    public function setCipherAlgo($cipherAlgo)
151
    {
152 2
        $this->cipherAlgo = $cipherAlgo;
153 2
    }
154
155
    /**
156
     * @return string
157
     */
158 3
    public function getCipherAlgo(): string
159
    {
160 3
        return $this->cipherAlgo;
161
    }
162
163
    /**
164
     * @param int $cipherIvLen
165
     */
166 1
    public function setCipherIvLen($cipherIvLen)
167
    {
168 1
        $this->cipherIvLen = $cipherIvLen;
169 1
    }
170
171
    /**
172
     * @return int
173
     */
174 1
    public function getCipherIvLen(): int
175
    {
176 1
        return $this->cipherIvLen;
177
    }
178
179
}