-
Notifications
You must be signed in to change notification settings - Fork 0
/
RijndaelOpenSSL.php
103 lines (90 loc) · 3.4 KB
/
RijndaelOpenSSL.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
class RijndaelOpenSSL
{
const METHOD = 'aes-256-cbc';
private $pbkdfBase = '';
private $pbkdfExtra = '';
private $pbkdfExtracount = 0;
private $pbkdfHashno = 0;
private $pbkdfState = 0;
private $iterations = 100;
public function reset()
{
$this->pbkdfBase = '';
$this->pbkdfExtra = '';
$this->pbkdfExtracount = 0;
$this->pbkdfHashno = 0;
$this->pbkdfState = 0;
}
public function decrypt($inputText, $password)
{
$this->reset();
$salt = (string) mb_strlen($password);
$key = $this->pbkdf1($password, $salt, 32);
$iv = $this->pbkdf1($password, $salt, 16);
$decrypted = openssl_decrypt(base64_decode($inputText), self::METHOD, $key, OPENSSL_RAW_DATA, $iv);
return mb_convert_encoding($decrypted, 'UTF-8', 'UTF-16LE');
}
public function encrypt($inputText, $password)
{
$this->reset();
$salt = (string) mb_strlen($password);
$key = $this->pbkdf1($password, $salt, 32);
$iv = $this->pbkdf1($password, $salt, 16);
$textUTF = mb_convert_encoding($inputText, 'UTF-16LE');
$encrypted = openssl_encrypt($textUTF, self::METHOD, $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($encrypted);
}
/**
* This code is not mine. It is based on: https://stackoverflow.com/questions/36511731/decrypting-string-encrypted-in-c-sharp-with-rijndaelmanaged-class-using-php
*/
private function pbkdf1($pass, $salt, $countBytes)
{
if ($this->pbkdfState == 0) {
$this->pbkdfHashno = 0;
$this->pbkdfState = 1;
$key = $pass . $salt;
$this->pbkdfBase = sha1($key, true);
for ($i = 2; $i < $this->iterations; $i++) {
$this->pbkdfBase = sha1($this->pbkdfBase, true);
}
}
$result = '';
if ($this->pbkdfExtracount > 0) {
$rlen = strlen($this->pbkdfExtra) - $this->pbkdfExtracount;
if ($rlen >= $countBytes) {
$result = substr($this->pbkdfExtra, $this->pbkdfExtracount, $countBytes);
if ($rlen > $countBytes) {
$this->pbkdfExtracount += $countBytes;
} else {
$this->pbkdfExtra = null;
$this->pbkdfExtracount = 0;
}
return $result;
}
$result = substr($this->pbkdfExtra, $rlen, $rlen);
}
$current = '';
$clen = 0;
$remain = $countBytes - strlen($result);
while ($remain > $clen) {
if ($this->pbkdfHashno == 0) {
$current = sha1($this->pbkdfBase, true);
} else if ($this->pbkdfHashno < 1000) {
$num = sprintf('%d', $this->pbkdfHashno);
$tmp = $num . $this->pbkdfBase;
$current .= sha1($tmp, true);
}
$this->pbkdfHashno++;
$clen = strlen($current);
}
// $current now holds at least as many bytes as we need
$result .= substr($current, 0, $remain);
// Save any left over bytes for any future requests
if ($clen > $remain) {
$this->pbkdfExtra = $current;
$this->pbkdfExtracount = $remain;
}
return $result;
}
}