ar_crypt   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 141
rs 10
c 0
b 0
f 0
ccs 0
cts 103
cp 0
wmc 26
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 27 5
A setApi() 0 3 1
A setKey() 0 17 4
A crypt() 0 17 3
A decrypt() 0 17 3
B pbkdf2() 0 47 10
1
<?php
2
	ar_pinp::allow( 'ar_crypt' );
3
4
	class ar_crypt extends arBase {
5
		private $key;
6
		private $encoding;
7
		private $iv;
0 ignored issues
show
Unused Code introduced by
The property $iv is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
8
		private $api;
9
		private $mode = MCRYPT_MODE_CBC;
10
11
		public function __construct( $key = null, $encoding = MCRYPT_RIJNDAEL_256, $api=0) {
12
			global $AR;
13
			$this->encoding = $encoding;
14
			$this->api      = $api;
15
			$this->key      = $key;
16
17
			if ($this->api === 0 ) {
18
				// this api will be deprecated in the future
19
				// we also try to be backwards compatible with pre php 5.6
20
21
				if ($key == null) {
22
					$key = $AR->sgSalt;
23
				}
24
25
				$keysizes = mcrypt_module_get_supported_key_sizes($this->encoding, $this->mode);
26
				sort($keysizes);
27
28
				$keysize = end ($keysizes);
29
				foreach($keysizes as $keysize){
30
					if($keysize >= strlen($key)) {
31
						break;
32
					}
33
				}
34
35
				$this->key = str_pad(substr($key,0,$keysize), $keysize, "\0");
36
			}
37
		}
38
39
		public function setApi($api) {
40
			$this->api = $api;
41
		}
42
43
		public function setKey( $key ) {
44
			if ($this->api === 0 ) {
45
				$keysizes = mcrypt_module_get_supported_key_sizes($this->encoding, $this->mode);
46
				sort($keysizes);
47
48
				$keysize = end ($keysizes);
49
				foreach($keysizes as $keysize){
50
					if($keysize > strlen($key)) {
51
						break;
52
					}
53
				}
54
				$this->key = str_pad(substr($key,0,$keysize), $keysize, "\0");
55
56
			} else {
57
				$this->key = $key;
58
			}
59
		}
60
61
		public function crypt( $value ) {
62
			if ($this->api === 0 ) {
63
				$iv = str_pad('',mcrypt_get_iv_size ( $this->encoding, $this->mode),"\0");
64
				return base64_encode(mcrypt_encrypt($this->encoding, $this->key, $value, $this->mode,$iv));
65
66
			} else {
67
				$ivsize = mcrypt_get_iv_size ( $this->encoding, $this->mode);
68
				$iv = mcrypt_create_iv ( $ivsize , MCRYPT_DEV_URANDOM);
69
70
				$encrypted = mcrypt_encrypt($this->encoding, $this->key, $value, $this->mode,$iv);
71
				if($encrypted !== false) {
72
					return base64_encode($iv . $encrypted);
73
				} else {
74
					return false;
75
				}
76
			}
77
		}
78
79
		public function decrypt( $value ) {
80
			if ($this->api === 0 ) {
81
				$iv = str_pad('',mcrypt_get_iv_size ( $this->encoding, $this->mode),"\0");
82
				return trim(mcrypt_decrypt($this->encoding, $this->key, base64_decode($value), $this->mode,$iv), "\0");
83
84
			} else {
85
				$decoded = base64_decode($value);
86
				$ivsize = mcrypt_get_iv_size ( $this->encoding, $this->mode);
87
				$iv = substr($decoded, 0, $ivsize);
88
				if($ivsize != strlen($iv)) {
89
					return false;
90
				}
91
92
				$encrypted = substr($decoded, $ivsize);
93
				return trim(mcrypt_decrypt($this->encoding, $this->key, $encrypted, $this->mode,$iv), "\0");
94
			}
95
		}
96
97
		public function pbkdf2($password, $salt, $count=5000, $key_length = null, $raw_output = true) {
98
			$algorithm = 'sha512';
99
100
			if(is_null($key_length)) {
101
				$key_length = mcrypt_get_key_size ( $this->encoding, $this->mode );
102
			}
103
104
			$algorithm = strtolower($algorithm);
105
			if(!in_array($algorithm, hash_algos(), true)){
106
				// fixme, return ar('error');
107
				trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);
108
			}
109
			if($count <= 0 || $key_length <= 0) {
110
				// fixme, return ar('error');
111
				trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);
112
			}
113
114
			if (function_exists("hash_pbkdf2")) {
115
				// The output length is in NIBBLES (4-bits) if $raw_output is false!
116
				if (!$raw_output) {
117
					$key_length = $key_length * 2;
118
				}
119
				return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output);
120
			}
121
122
			$hash_length = strlen(hash($algorithm, "", true));
123
			$block_count = ceil($key_length / $hash_length);
124
125
			$output = "";
126
			for($i = 1; $i <= $block_count; $i++) {
127
				// $i encoded as 4 bytes, big endian.
128
				$last = $salt . pack("N", $i);
129
				// first iteration
130
				$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
131
				// perform the other $count - 1 iterations
132
				for ($j = 1; $j < $count; $j++) {
133
					$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
134
				}
135
				$output .= $xorsum;
136
			}
137
138
			if($raw_output){
139
				return substr($output, 0, $key_length);
140
			} else {
141
				return base64_encode(substr($output, 0, $key_length));
142
			}
143
		}
144
	}
145