Subversion Repositories cheapmusic

Rev

Rev 9 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 - 1
<?php
2
/**
3
 * Openssl encrypt/decrypt functions
4
 *
5
 * Available under the MIT License
6
 *
7
 * The MIT License (MIT)
8
 * Copyright (c) 2016 ionCube Ltd.
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
11
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
12
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
13
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
16
 * the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
19
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
20
 * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21
 * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 */
23
class Cryptor
24
{
25
    private static $instance = null;
26
    private static $cipher_algo;
27
    private static $hash_algo;
28
    private static $keystring;
29
    private static $iv_num_bytes;
30
    private static $format;
9 - 31
    private static $hasOpenSSL = true;
7 - 32
    const FORMAT_RAW = 0;
33
    const FORMAT_B64 = 1;
34
    const FORMAT_HEX = 2;
35
 
36
    /**
37
     * Create a Cryptor singleton instance
38
     * @param array $cryptConfig The cipher algorithm, the hash algorithm and the key.
39
     * @param [type] $fmt         Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX. Default: FORMAT_B64.
40
     */
10 - 41
    public static function getInstance($cryptorConfig = null, $fmt = Cryptor::FORMAT_B64)
7 - 42
    {
43
        if (is_null(self::$instance)){
44
            self::$instance = new self();
9 - 45
            if (!extension_loaded("openssl")) {
46
                self::$hasOpenSSL = false;
47
                return self::$instance;
48
            }
7 - 49
        } else {
50
            return self::$instance;
51
        }
52
        // store cryptor configuration
53
        if (!is_null($cryptorConfig)) {
54
            if (isset($cryptorConfig['cipherAlgorithm']) && !empty($cryptorConfig['cipherAlgorithm'])) {
55
                self::$cipher_algo = $cryptorConfig['cipherAlgorithm'];
56
            } else {
57
                self::$cipher_algo = 'aes-256-cbc';
58
            }
59
            if (isset($cryptorConfig['hashAlgorithm']) && !empty($cryptorConfig['hashAlgorithm'])) {
60
                self::$hash_algo = $cryptorConfig['hashAlgorithm'];
61
            } else {
62
                self::$hash_algo = 'sha256';
63
            }
64
            if (isset($cryptorConfig['key']) && !empty($cryptorConfig['key'])) {
65
                self::$keystring = $cryptorConfig['key'];
66
            } else {
67
                throw new \Exception("Cryptor:: - key not set in configuration");
68
            }
69
            if ($fmt === Cryptor::FORMAT_RAW || $fmt === Cryptor::FORMAT_B64 || $fmt == Cryptor::FORMAT_HEX) {
70
                self::$format = $fmt;
71
            } else {
72
                self::$format = Cryptor::FORMAT_B64;
73
            }
74
        }
75
 
76
        if (!in_array(self::$cipher_algo, openssl_get_cipher_methods(true)))
77
        {
78
            throw new \Exception("Cryptor:: - unknown cipher algo {" . self::$cipher_algo . "}");
79
        }
80
 
81
        if (!in_array(self::$hash_algo, openssl_get_md_methods(true)))
82
        {
83
            throw new \Exception("Cryptor:: - unknown hash algo {" . self::$hash_algo . "}");
84
        }
85
 
86
        self::$iv_num_bytes = openssl_cipher_iv_length(self::$cipher_algo);
87
 
88
        return self::$instance;
89
    }
90
    /**
91
     * Encrypt a string.
92
     * @param  string $in  String to encrypt.
93
     * @param  string $key Optional encryption key.
94
     * @param  int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
95
     * @return string      The encrypted string.
96
     */
10 - 97
    public static function encryptString($in, $key = null, $fmt = null)
7 - 98
    {
9 - 99
        if (!self::$hasOpenSSL) {
100
            return base64_encode($in);
101
        }
7 - 102
        if ($fmt === null)
103
        {
104
            $fmt = self::$format;
105
        }
106
        if ($key === null)
107
        {
108
            $key = self::$keystring;
109
        }
110
        // Build an initialization vector
111
        $iv = openssl_random_pseudo_bytes(self::$iv_num_bytes, $isStrongCrypto);
112
        if (!$isStrongCrypto) {
113
            throw new \Exception("Cryptor::encryptString() - Not a strong key");
114
        }
115
        // Hash the key
116
        $keyhash = openssl_digest($key, self::$hash_algo, true);
117
        // and encrypt
118
        $opts =  OPENSSL_RAW_DATA;
119
        $encrypted = openssl_encrypt($in, self::$cipher_algo, $keyhash, $opts, $iv);
120
        if ($encrypted === false)
121
        {
122
            throw new \Exception('Cryptor::encryptString() - Encryption failed: ' . openssl_error_string());
123
        }
124
        // The result comprises the IV and encrypted data
125
        $res = $iv . $encrypted;
126
        // and format the result if required.
127
        if ($fmt == Cryptor::FORMAT_B64)
128
        {
129
            $res = base64_encode($res);
130
        }
131
        else if ($fmt == Cryptor::FORMAT_HEX)
132
        {
133
            $res = unpack('H*', $res)[1];
134
        }
135
        return $res;
136
    }
137
    /**
138
     * Decrypt a string.
139
     * @param  string $in  String to decrypt.
140
     * @param  string $key Optional decryption key.
141
     * @param  int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
142
     * @return string      The decrypted string.
143
     */
10 - 144
    public static function decryptString($in, $key = null, $fmt = null)
7 - 145
    {
9 - 146
        if (!self::$hasOpenSSL) {
147
            return base64_decode($in);
148
        }
7 - 149
        if ($fmt === null)
150
        {
151
            $fmt = self::$format;
152
        }
153
        if ($key === null)
154
        {
155
            $key = self::$keystring;
156
        }
157
        $raw = $in;
158
        // Restore the encrypted data if encoded
159
        if ($fmt == Cryptor::FORMAT_B64)
160
        {
161
            $raw = base64_decode($in);
162
        }
163
        else if ($fmt == Cryptor::FORMAT_HEX)
164
        {
165
            $raw = pack('H*', $in);
166
        }
167
        // and do an integrity check on the size.
168
        if (strlen($raw) < self::$iv_num_bytes)
169
        {
170
            throw new \Exception('Cryptor::decryptString() - ' .
171
                'data length ' . strlen($raw) . " is less than iv length {self::$iv_num_bytes}");
172
        }
173
        // Extract the initialization vector and encrypted data
174
        $iv = substr($raw, 0, self::$iv_num_bytes);
175
        $raw = substr($raw, self::$iv_num_bytes);
176
        // Hash the key
177
        $keyhash = openssl_digest($key, self::$hash_algo, true);
178
        // and decrypt.
179
        $opts = OPENSSL_RAW_DATA;
180
        $res = openssl_decrypt($raw, self::$cipher_algo, $keyhash, $opts, $iv);
181
        if ($res === false)
182
        {
183
            throw new \Exception('Cryptor::decryptString - decryption failed: ' . openssl_error_string());
184
        }
185
        return $res;
186
    }
187
    /**
188
     * Static convenience method for encrypting.
189
     * @param  string $in  String to encrypt.
190
     * @param  string $key Optional encryption key.
191
     * @param  int $fmt Optional override for the output encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
192
     * @return string      The encrypted string.
193
     */
194
    public static function Encrypt($in, $key = null, $fmt = null)
195
    {
196
        return self::encryptString($in, $key, $fmt);
197
    }
198
    /**
199
     * Static convenience method for decrypting.
200
     * @param  string $in  String to decrypt.
201
     * @param  string $key Optinal eecryption key.
202
     * @param  int $fmt Optional override for the input encoding. One of FORMAT_RAW, FORMAT_B64 or FORMAT_HEX.
203
     * @return string      The decrypted string.
204
     */
205
    public static function Decrypt($in, $key = null, $fmt = null)
206
    {
207
        return self::decryptString($in, $key, $fmt);
208
    }
10 - 209
}