Rev 58 | Rev 60 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 58 | Rev 59 | ||
---|---|---|---|
Line 54... | Line 54... | ||
54 | 54 | ||
55 | */ |
55 | */ |
56 | 56 | ||
57 | define('OID_MCF_VTS_V1', '1.3.6.1.4.1.37476.3.0.1.1'); // { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 specifications(3) misc(0) modular-crypt-format(1) vts-crypt-v1(1) } |
57 | define('OID_MCF_VTS_V1', '1.3.6.1.4.1.37476.3.0.1.1'); // { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 37476 specifications(3) misc(0) modular-crypt-format(1) vts-crypt-v1(1) } |
58 | 58 | ||
59 | function crypt_radix64($str) { |
- | |
60 | $rfc4648_base64 = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '+', '/', '='); |
59 | define('BASE64_RFC4648_ALPHABET', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/='); |
61 | $crypt_base64 = array('.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ''); |
60 | define('BASE64_CRYPT_ALPHABET', './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz '); |
62 | 61 | ||
- | 62 | function crypt_radix64_encode($str) { |
|
- | 63 | $x = $str; |
|
63 | $x = base64_encode($str); |
64 | $x = base64_encode($x); |
64 | $x = str_replace($rfc4648_base64, $crypt_base64, $x); |
65 | $x = trim(strtr($x, BASE64_RFC4648_ALPHABET, BASE64_CRYPT_ALPHABET)); |
65 | return $x; |
66 | return $x; |
66 | } |
67 | } |
67 | 68 | ||
- | 69 | function crypt_radix64_decode($str) { |
|
- | 70 | $x = $str; |
|
- | 71 | $x = trim(strtr($x, BASE64_CRYPT_ALPHABET, BASE64_RFC4648_ALPHABET)); |
|
- | 72 | $x = base64_decode($x); |
|
- | 73 | return $x; |
|
- | 74 | } |
|
- | 75 | ||
- | 76 | assert(crypt_radix64_decode(crypt_radix64_encode('hallo'))); |
|
- | 77 | ||
68 | function crypt_modular_format($id, $bin_salt, $bin_hash, $params=null) { |
78 | function crypt_modular_format($id, $bin_salt, $bin_hash, $params=null) { |
69 | // $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] |
79 | // $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]] |
70 | $out = '$'.$id; |
80 | $out = '$'.$id; |
71 | if (!is_null($params)) { |
81 | if (!is_null($params)) { |
72 | $ary_params = array(); |
82 | $ary_params = array(); |
Line 74... | Line 84... | ||
74 | foreach ($params as $name => $value) { |
84 | foreach ($params as $name => $value) { |
75 | $ary_params[] = "$name=$value"; |
85 | $ary_params[] = "$name=$value"; |
76 | } |
86 | } |
77 | $out .= '$'.implode(',',$ary_params); |
87 | $out .= '$'.implode(',',$ary_params); |
78 | } |
88 | } |
79 | $out .= '$'.crypt_radix64($bin_salt); |
89 | $out .= '$'.crypt_radix64_encode($bin_salt); |
80 | $out .= '$'.crypt_radix64($bin_hash); |
90 | $out .= '$'.crypt_radix64_encode($bin_hash); |
81 | return $out; |
91 | return $out; |
82 | } |
92 | } |
83 | 93 | ||
- | 94 | function crypt_modular_format_decode($mcf) { |
|
- | 95 | $ary = explode('$', $mcf); |
|
- | 96 | ||
- | 97 | $dummy = array_shift($ary); |
|
- | 98 | if ($dummy !== '') return false; |
|
- | 99 | ||
- | 100 | $dummy = array_shift($ary); |
|
- | 101 | $id = $dummy; |
|
- | 102 | ||
- | 103 | $params = array(); |
|
- | 104 | $dummy = array_shift($ary); |
|
- | 105 | if (strpos($dummy, '=') !== false) { |
|
- | 106 | $params_ary = explode(',',$dummy); |
|
- | 107 | foreach ($params_ary as $param) { |
|
- | 108 | $bry = explode('=', $param, 2); |
|
- | 109 | if (count($bry) > 1) { |
|
- | 110 | $params[$bry[0]] = $bry[1]; |
|
- | 111 | } |
|
- | 112 | } |
|
- | 113 | } else { |
|
- | 114 | array_unshift($ary, $dummy); |
|
- | 115 | } |
|
- | 116 | ||
- | 117 | if (count($ary) > 1) { |
|
- | 118 | $dummy = array_shift($ary); |
|
- | 119 | $bin_salt = crypt_radix64_decode($dummy); |
|
- | 120 | } else { |
|
- | 121 | $bin_salt = ''; |
|
- | 122 | } |
|
- | 123 | ||
- | 124 | $dummy = array_shift($ary); |
|
- | 125 | $bin_hash = crypt_radix64_decode($dummy); |
|
- | 126 | ||
- | 127 | return array('id' => $id, 'salt' => $bin_salt, 'hash' => $bin_hash, 'params' => $params); |
|
- | 128 | } |
|
- | 129 | ||
84 | function vts_crypt($algo, $str_password, $str_salt, $ver='1', $mode='ps') { |
130 | function vts_crypt($algo, $str_password, $str_salt, $ver='1', $mode='ps') { |
85 | if ($ver == '1') { |
131 | if ($ver == '1') { |
86 | if ($mode == 'sp') { |
132 | if ($mode == 'sp') { |
87 | $payload = $str_salt.$str_password; |
133 | $payload = $str_salt.$str_password; |
88 | if (($algo === 'sha3-512') && !in_array($algo, hash_algos()) && function_exists('sha3_512')) { |
134 | if (($algo === 'sha3-512') && !in_array($algo, hash_algos()) && function_exists('sha3_512')) { |
Line 115... | Line 161... | ||
115 | throw new Exception("Invalid VTS crypt version 1 mode. Expect sp, ps, sps, or hmac."); |
161 | throw new Exception("Invalid VTS crypt version 1 mode. Expect sp, ps, sps, or hmac."); |
116 | } |
162 | } |
117 | $bin_salt = $str_salt; |
163 | $bin_salt = $str_salt; |
118 | return crypt_modular_format(OID_MCF_VTS_V1, $bin_salt, $bin_hash, array('a'=>$algo,'m'=>$mode)); |
164 | return crypt_modular_format(OID_MCF_VTS_V1, $bin_salt, $bin_hash, array('a'=>$algo,'m'=>$mode)); |
119 | } else { |
165 | } else { |
120 | throw new Exception("Invalid VTS crypt version, except 1."); |
166 | throw new Exception("Invalid VTS crypt version, expect 1."); |
121 | } |
167 | } |
122 | } |
168 | } |
123 | 169 | ||
124 | function vts_crypt_convert_from_old_oidplus($authkey, $salt) { |
170 | function vts_crypt_convert_from_old_oidplus($authkey, $salt) { |
125 | if (preg_match('@^A1([abcd])#(.+):(.+)$@', $authkey, $m)) { |
171 | if (preg_match('@^A1([abcd])#(.+):(.+)$@', $authkey, $m)) { |
126 | // A1a#hashalgo:X with X being H(salt+password) in hex- or base64-notation |
172 | // A1a#hashalgo:X with X being H(salt+password) in hex- or rfc4648-base64-notation |
127 | // A1b#hashalgo:X with X being H(password+salt) in hex- or base64-notation |
173 | // A1b#hashalgo:X with X being H(password+salt) in hex- or rfc4648-base64-notation |
128 | // A1c#hashalgo:X with X being H(salt+password+salt) in hex- or base64-notation |
174 | // A1c#hashalgo:X with X being H(salt+password+salt) in hex- or rfc4648-base64-notation |
129 | // A1d#hashalgo:X with X being H_HMAC(password,salt) in hex- or base64-notation |
175 | // A1d#hashalgo:X with X being H_HMAC(password,salt) in hex- or rfc4648-base64-notation |
130 | $mode = ''; // avoid PHPstan warning |
176 | $mode = ''; // avoid PHPstan warning |
131 | if ($m[1] == 'a') $mode = 'sp'; |
177 | if ($m[1] == 'a') $mode = 'sp'; |
132 | else if ($m[1] == 'b') $mode = 'ps'; |
178 | else if ($m[1] == 'b') $mode = 'ps'; |
133 | else if ($m[1] == 'c') $mode = 'sps'; |
179 | else if ($m[1] == 'c') $mode = 'sps'; |
134 | else if ($m[1] == 'd') $mode = 'hmac'; |
180 | else if ($m[1] == 'd') $mode = 'hmac'; |
Line 140... | Line 186... | ||
140 | } else { |
186 | } else { |
141 | $bin_hash = hex2bin($m[3]); |
187 | $bin_hash = hex2bin($m[3]); |
142 | } |
188 | } |
143 | return crypt_modular_format(OID_MCF_VTS_V1, $bin_salt, $bin_hash, array('a'=>$algo,'m'=>$mode)); |
189 | return crypt_modular_format(OID_MCF_VTS_V1, $bin_salt, $bin_hash, array('a'=>$algo,'m'=>$mode)); |
144 | } else if (preg_match('@^A2#(.+)$@', $authkey, $m)) { |
190 | } else if (preg_match('@^A2#(.+)$@', $authkey, $m)) { |
145 | // A2#X with X being sha3(salt+password) in base64-notation |
191 | // A2#X with X being sha3(salt+password) in rfc4648-base64-notation |
146 | $mode = 'sp'; |
192 | $mode = 'sp'; |
147 | $algo = 'sha3-512'; |
193 | $algo = 'sha3-512'; |
148 | $bin_salt = $salt; |
194 | $bin_salt = $salt; |
149 | $bin_hash = base64_decode($m[1]); |
195 | $bin_hash = base64_decode($m[1]); |
150 | return crypt_modular_format(OID_MCF_VTS_V1, $bin_salt, $bin_hash, array('a'=>$algo,'m'=>$mode)); |
196 | return crypt_modular_format(OID_MCF_VTS_V1, $bin_salt, $bin_hash, array('a'=>$algo,'m'=>$mode)); |