-
Notifications
You must be signed in to change notification settings - Fork 1
/
crypt.php
150 lines (121 loc) · 3.61 KB
/
crypt.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
class Crypto {
/**
* For the Encrypt/Decrypt functions
* Output Encoding (format)
* 0: RAW
* 1: B64
* 2: HEX
*/
private $format;
private $cipher;
private $hash;
/**
* Constructor
* @param string $cipher A valid (prolly) AES cipher
* @param string $hash A valid hashing method
* @param string $format 'raw', 'b64' or 'hex'
*/
public function __construct(string $cipher='aes-256-ctr', string $hash ='sha256', string $format ='b64'){
$format = strtolower($format);
if($format == 'raw')
$this->format = 0;
elseif($format == 'hex')
$this->format = 2;
else
$this->format = 1;
$this->cipher = $cipher;
$this->hash = $hash;
}
/**
* Returns the current settings.
* Used during testing
* @return string Format, Cipher and Hash setting
*/
public function __toString(){
return "[Format: ".$this->format."]
[Cipher: ".$this->cipher."]
[Hash: ".$this->hash."]";
}
/**
* Returns available cipher methods
* TODO: this needs refactoring
*/
public function GetCiphers() {
foreach (openssl_get_cipher_methods() as $cipher) {
echo $cipher.'<br>';
}
}
/**
* Returns available hashing algorithms
* TODO: this needs refactoring
*/
public function GetHashes() {
foreach (openssl_get_md_methods() as $hash) {
echo $hash.'<br>';
}
}
/**
* This function will Encrypt your data
* @param string $string Data to be encrypted
* @param string $key Encryption key
* @return string The encrypted string
*/
public function encrypt(string $string, string $key) {
# Confirm the Cipher and Hash methods are available
# TODO: Refactor here as well
if(!in_array($this->cipher, openssl_get_cipher_methods(true)))
return "Unknown cipher! Available ciphers are;<br>".GetCiphers();
if(!in_array($this->hash, openssl_get_md_methods(true)))
return "Unknown hash! Available hashing methods are;<br>".GetHashes();
# Random Initialization Vector
$length = openssl_cipher_iv_length($this->cipher);
if(function_exists('random_bytes'))
$bytes = random_bytes($length);
else
$bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
# Hash the key
$keyhash = openssl_digest($key, $this->hash, true);
# Encrypt
$encrypt = openssl_encrypt($string, $this->cipher, $keyhash, OPENSSL_RAW_DATA, $bytes);
# Confirm the action completed
if($encrypt == false)
return "Something went wrong: ".openssl_error_string();
$result = $bytes.$encrypt;
# Format the result
if($this->format == 1)
$result = base64_encode($result);
elseif($this->format == 2)
$result = unpack('H*', $result)[1];
return $result;
}
/**
* This function will Decrypt your data
* @param string $string The encoded message to decrypt
* @param string $key The key to Decrypt the message with
* @return string Returns the decrypted message
*/
public function decrypt(string $string, string $key) {
# Format
if($this->format == 1)
$string = base64_decode($string);
if($this->format == 2)
$string = pack('H*', $string);
# Integrity check
$length = openssl_cipher_iv_length($this->cipher);
if(strlen($string) < $length)
return "Data length ".strlen($string)." is less than byte (iv) length ".$length;
# Extract the Initialization Vector
$byte = substr($string, 0, $length);
$string = substr($string, $length);
# Hash the key
$keyhash = openssl_digest($key, $this->hash, true);
# Decrypt
$decrypt = openssl_decrypt($string, $this->cipher, $keyhash, OPENSSL_RAW_DATA, $byte);
# Confirm the action completed
if($decrypt == false)
return "Decryption failed: ".openssl_error_string();
return $decrypt;
}
}
?>