CryptoGuard::generateIv()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Coreproc\CryptoGuard;
4
5
use Coreproc\CryptoGuard\Exceptions\InvalidPayloadException;
6
use Exception;
7
8
class CryptoGuard
9
{
10
11
    private $passphrase;
12
    private $key;
13
    private $salt;
14
    private $iv;
15
16
    public function __construct($passphrase)
17
    {
18
        $this->passphrase = $passphrase;
19
    }
20
21
    /**
22
     * Encrypt a string
23
     *
24
     * @param string $plaintext
25
     * @return string
26
     */
27
    public function encrypt($plaintext)
28
    {
29
        $this->generateSalt();
30
        $this->generateIv();
31
32
        $this->generateKey($this->passphrase);
33
34
        $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $plaintext, MCRYPT_MODE_CBC, $this->iv);
35
36
        $dataReturn = array();
37
        $dataReturn['iv'] = base64_encode($this->iv);
38
        $dataReturn['salt'] = base64_encode($this->salt);
39
        $dataReturn['ciphertext'] = base64_encode($ciphertext);
40
        $dataReturn['sig'] = base64_encode($this->hmacSign($ciphertext . $this->salt, $this->iv));
41
42
        return base64_encode(json_encode($dataReturn));
43
    }
44
45
    /**
46
     * Decrypt the encrypted string
47
     *
48
     * @param $dataEnciphered
49
     * @return string
50
     * @throws Exception
51
     */
52
    public function decrypt($dataEnciphered)
53
    {
54
        $dataDecoded = json_decode(base64_decode($dataEnciphered), true);
55
56
        $this->setIv(base64_decode($dataDecoded['iv']));
57
        $this->setSalt(base64_decode($dataDecoded['salt']));
58
        $this->generateKey($this->passphrase);
59
60
        $ciphertext = base64_decode($dataDecoded['ciphertext']);
61
62
        $originalSignature = base64_decode($dataDecoded['sig']);
63
64
        // Attempt to verify signature
65
        if ($this->hmacVerify($originalSignature . $ciphertext . $this->salt, $this->iv) == false) {
66
            throw new InvalidPayloadException();
67
        }
68
69
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $ciphertext, MCRYPT_MODE_CBC, $this->iv));
70
    }
71
72
    private function setSalt($salt)
73
    {
74
        $this->salt = $salt;
75
    }
76
77
    private function generateSalt()
78
    {
79
        $this->salt = mcrypt_create_iv(32, MCRYPT_DEV_RANDOM); // abuse IV function for random salt
80
    }
81
82
    private function setIv($iv)
83
    {
84
        $this->iv = $iv;
85
    }
86
87
    private function generateIv()
88
    {
89
        $this->iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
90
    }
91
92
    private function generateKey($passphrase, $iterations = 10000, $length = 32)
93
    {
94
        $this->key = hash_pbkdf2('sha256', $passphrase, $this->salt, $iterations, $length);
95
    }
96
97
    private function hmacSign($ciphertext, $key)
98
    {
99
        return hash_hmac('sha256', $ciphertext, $key);
100
    }
101
102
    /**
103
     * @param $bundle
104
     * @param $key
105
     * @return bool
106
     */
107
    private function hmacVerify($bundle, $key)
108
    {
109
        $msgMAC = mb_substr($bundle, 0, 64, '8bit');
110
        $message = mb_substr($bundle, 64, null, '8bit');
111
112
        return hash_equals(
113
            hash_hmac('sha256', $message, $key),
114
            $msgMAC
115
        );
116
    }
117
118
}