Completed
Push — master ( 994503...2fd93e )
by Richard
01:27
created

EloquentEncryption::decryptString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace RichardStyles\EloquentEncryption;
4
5
use Illuminate\Contracts\Encryption\Encrypter;
6
use Illuminate\Support\Facades\Config;
7
use phpseclib\Crypt\RSA;
8
use RichardStyles\EloquentEncryption\Contracts\RsaKeyHandler;
9
use RichardStyles\EloquentEncryption\Exceptions\InvalidRsaKeyHandler;
10
use RichardStyles\EloquentEncryption\Exceptions\RSAKeyFileMissing;
11
use RichardStyles\EloquentEncryption\FileSystem\RsaKeyStorageHandler;
12
13
class EloquentEncryption implements Encrypter
14
{
15
16
    /**
17
     * @var RsaKeyHandler
18
     */
19
    private $handler;
20
21
    /**
22
     * ApplicationKey constructor.
23
     */
24
    public function __construct()
25
    {
26
        $this->handler = app()->make(
27
            Config::get('eloquent_encryption.handler', RsaKeyStorageHandler::class)
28
        );
29
30
        if(!$this->handler instanceof RsaKeyHandler){
31
            throw new InvalidRsaKeyHandler;
32
        }
33
    }
34
35
    /**
36
     * Have any RSA keys been generated
37
     *
38
     * @return bool
39
     */
40
    public function exists()
41
    {
42
        return $this->handler->exists();
43
    }
44
45
    /**
46
     * Generate a set of RSA Keys which will be used to encrypt the database fields
47
     */
48
    public function makeEncryptionKeys()
49
    {
50
        $key = $this->createKey(Config::get('eloquent_encryption.key.email'));
51
        $this->handler->saveKey($key['publickey'], $key['privatekey']);
52
    }
53
54
    /**
55
     * Create a digital set of RSA keys, defaulting to 4096-bit
56
     *
57
     * @param string $email
58
     * @return array
59
     */
60
    public function createKey($email = '')
61
    {
62
        $rsa = new RSA();
63
        $rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_OPENSSH);
64
        $rsa->setComment($email);
65
66
        return $rsa->createKey(Config::get('eloquent_encryption.key.length', 4096));
67
    }
68
69
    /**
70
     * Helper function to ensure RSA options match for encrypting/decrypting
71
     *
72
     * @param $key
73
     * @return RSA
74
     */
75
    private function getRsa($key)
76
    {
77
        $rsa = new RSA();
78
        $rsa->loadKey($key);
79
        $rsa->setEncryptionMode(RSA::ENCRYPTION_OAEP);
80
81
        return $rsa;
82
    }
83
84
    /**
85
     * Encrypt a value using the RSA key
86
     *
87
     * @param $value
88
     * @param bool $serialize
89
     * @return false|string
90
     * @throws RSAKeyFileMissing
91
     */
92
    public function encrypt($value, $serialize = true)
93
    {
94
        return $this->getRsa($this->handler->getPublicKey())
95
            ->encrypt($serialize ? serialize($value) : $value);
96
    }
97
98
    /**
99
     * Encrypt a string without serialization.
100
     *
101
     * @param  string  $value
102
     * @return string
103
     *
104
     * @throws RSAKeyFileMissing
105
     */
106
    public function encryptString($value)
107
    {
108
        return $this->encrypt($value, false);
109
    }
110
111
    /**
112
     * Decrypt a value using the RSA key
113
     *
114
     * @param $value
115
     * @param  bool  $unserialize
116
     * @return false|string|null
117
     * @throws RSAKeyFileMissing
118
     */
119
    public function decrypt($value, $unserialize = true)
120
    {
121
        if (empty($value)) {
122
            return null;
123
        }
124
125
        $decrypted = $this->getRsa($this->handler->getPrivateKey())
126
            ->decrypt($value);
127
128
        return $unserialize ? unserialize($decrypted) : $decrypted;
129
    }
130
131
    /**
132
     * Decrypt the given string without unserialization.
133
     *
134
     * @param  string  $payload
135
     * @return string
136
     *
137
     * @throws RSAKeyFileMissing
138
     */
139
    public function decryptString($payload)
140
    {
141
        return $this->decrypt($payload, false);
142
    }
143
144
    public function __call($name, $arguments)
145
    {
146
        if(method_exists($this->handler, $name)){
147
            return $this->handler->{$name}($arguments);
148
        }
149
    }
150
}
151