3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 class GeneralSecurityException extends Exception {
27 * HMAC algorithm to use
29 private static $HMAC_TYPE = "HMACSHA1";
32 * minimum safe length for hmac keys (this is good practice, but not
33 * actually a requirement of the algorithm
35 private static $MIN_HMAC_KEY_LEN = 8;
38 * Encryption algorithm to use
40 private static $CIPHER_TYPE = "AES/CBC/PKCS5Padding";
42 private static $CIPHER_KEY_TYPE = "AES";
45 * Use keys of this length for encryption operations
47 public static $CIPHER_KEY_LEN = 16;
49 private static $CIPHER_BLOCK_SIZE = 16;
52 * Length of HMAC SHA1 output
54 public static $HMAC_SHA1_LEN = 20;
56 private function __construct() {}
58 public static function hmacSha1Verify($key, $in, $expected) {
59 $hmac = Crypto::hmacSha1($key, $in);
60 if ($hmac != $expected) {
61 throw new GeneralSecurityException("HMAC verification failure");
65 public static function aes128cbcEncrypt($key, $text) {
67 $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
69 throw new GeneralSecurityException('Invalid mcrypt cipher, check your libmcrypt library and php-mcrypt extention');
71 // replaced MCRYPT_DEV_RANDOM with MCRYPT_RAND since windows doesn't have /dev/rand :)
72 srand((double)microtime() * 1000000);
73 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
74 /* Intialize encryption */
75 mcrypt_generic_init($td, $key, $iv);
77 $encrypted = mcrypt_generic($td, $text);
78 /* Terminate encryption handler */
79 mcrypt_generic_deinit($td);
81 * AES-128-CBC encryption. The IV is returned as the first 16 bytes
84 return $iv . $encrypted;
87 public static function aes128cbcDecrypt($key, $encrypted_text) {
89 $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
90 if (is_callable('mb_substr')) {
91 $iv = mb_substr($encrypted_text, 0, Crypto::$CIPHER_BLOCK_SIZE, 'latin1');
93 $iv = substr($encrypted_text, 0, Crypto::$CIPHER_BLOCK_SIZE);
95 /* Initialize encryption module for decryption */
96 mcrypt_generic_init($td, $key, $iv);
97 /* Decrypt encrypted string */
98 if (is_callable('mb_substr')) {
99 $encrypted = mb_substr($encrypted_text, Crypto::$CIPHER_BLOCK_SIZE, mb_strlen($encrypted_text, 'latin1'), 'latin1');
101 $encrypted = substr($encrypted_text, Crypto::$CIPHER_BLOCK_SIZE);
103 $decrypted = mdecrypt_generic($td, $encrypted);
104 /* Terminate decryption handle and close module */
105 mcrypt_generic_deinit($td);
106 mcrypt_module_close($td);
108 return trim($decrypted);
111 public static function hmacSha1($key, $data) {
114 if (strlen($key) > $blocksize) {
115 $key = pack('H*', $hashfunc($key));
117 $key = str_pad($key, $blocksize, chr(0x00));
118 $ipad = str_repeat(chr(0x36), $blocksize);
119 $opad = str_repeat(chr(0x5c), $blocksize);
120 $hmac = pack('H*', $hashfunc(($key ^ $opad) . pack('H*', $hashfunc(($key ^ $ipad) . $data))));