可与java、c#的3DES(DESede)加密方式兼容
Пример #1
0
 /**
  * 初始化方法,数据库配置、连接初始化
  * @return void
  */
 public function __construct()
 {
     $dbconfig = array();
     $_config = C('ONLINE_DB');
     $dbconfig['DB_TYPE'] = isset($_config['DB_TYPE']) ? $_config['DB_TYPE'] : C('DB_TYPE');
     $dbconfig['DB_HOST'] = isset($_config['DB_HOST']) ? $_config['DB_HOST'] : C('DB_HOST');
     $dbconfig['DB_NAME'] = isset($_config['DB_NAME']) ? $_config['DB_NAME'] : C('DB_NAME');
     $dbconfig['DB_USER'] = isset($_config['DB_USER']) ? $_config['DB_USER'] : C('DB_USER');
     $dbconfig['DB_PWD'] = isset($_config['DB_PWD']) ? $_config['DB_PWD'] : C('DB_PWD');
     $dbconfig['DB_PORT'] = isset($_config['DB_PORT']) ? $_config['DB_PORT'] : C('DB_PORT');
     $dbconfig['DB_PREFIX'] = isset($_config['DB_PREFIX']) ? $_config['DB_PREFIX'] : C('DB_PREFIX');
     $dbconfig['DB_CHARSET'] = isset($_config['DB_CHARSET']) ? $_config['DB_CHARSET'] : C('DB_CHARSET');
     $db_pwd = $dbconfig['DB_PWD'];
     if ($dbconfig['DB_ENCRYPT'] == 1) {
         if ($db_pwd != '') {
             require_once SITE_PATH . '/addons/library/CryptDES.php';
             $crypt = new CryptDES();
             $db_pwd = (string) $crypt->decrypt($db_pwd);
         }
     }
     // 重设Service的数据连接信息
     $connection = array('dbms' => $dbconfig['DB_TYPE'], 'hostname' => $dbconfig['DB_HOST'], 'hostport' => $dbconfig['DB_PORT'], 'database' => $dbconfig['DB_NAME'], 'username' => $dbconfig['DB_USER'], 'password' => $db_pwd);
     // 实例化Online数据库连接
     $this->odb = new Db($connection);
     $this->today = date('Y-m-d');
     $this->todayTimestamp = strtotime(date('Y-m-d'));
 }
Пример #2
0
 /**
 * Break a public or private key down into its constituant components
 *
 * @access private
 * @see _convertPublicKey()
 * @see _convertPrivateKey()
 * @param String $key
 * @param Integer $type
 * @return Array
 */
 function _parseKey($key, $type)
 {
     if ($type != CRYPT_RSA_PUBLIC_FORMAT_RAW && !is_string($key)) {
         return false;
     }
     switch ($type) {
         case CRYPT_RSA_PUBLIC_FORMAT_RAW:
             if (!is_array($key)) {
                 return false;
             }
             $components = array();
             switch (true) {
                 case isset($key['e']):
                     $components['publicExponent'] = $key['e']->copy();
                     break;
                 case isset($key['exponent']):
                     $components['publicExponent'] = $key['exponent']->copy();
                     break;
                 case isset($key['publicExponent']):
                     $components['publicExponent'] = $key['publicExponent']->copy();
                     break;
                 case isset($key[0]):
                     $components['publicExponent'] = $key[0]->copy();
             }
             switch (true) {
                 case isset($key['n']):
                     $components['modulus'] = $key['n']->copy();
                     break;
                 case isset($key['modulo']):
                     $components['modulus'] = $key['modulo']->copy();
                     break;
                 case isset($key['modulus']):
                     $components['modulus'] = $key['modulus']->copy();
                     break;
                 case isset($key[1]):
                     $components['modulus'] = $key[1]->copy();
             }
             switch (true) {
                 case isset($key['d']):
                     $components['privateExponent'] = $key['d']->copy();
                     break;
                 case isset($key['privateExponent']):
                     $components['privateExponent'] = $key['privateExponent']->copy();
                     break;
                 case isset($key[2]):
                     $components['privateExponent'] = $key[2]->copy();
             }
             return $components;
         case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
         case CRYPT_RSA_PUBLIC_FORMAT_PKCS1:
             /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
                 "outside the scope" of PKCS#1.  PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
                 protect private keys, however, that's not what OpenSSL* does.  OpenSSL protects private keys by adding
                 two new "fields" to the key - DEK-Info and Proc-Type.  These fields are discussed here:
             
                 http://tools.ietf.org/html/rfc1421#section-4.6.1.1
                 http://tools.ietf.org/html/rfc1421#section-4.6.1.3
             
                 DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
                 DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
                 function.  As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
                 own implementation.  ie. the implementation *is* the standard and any bugs that may exist in that
                 implementation are part of the standard, as well.
             
                 * OpenSSL is the de facto standard.  It's utilized by OpenSSH and other projects */
             if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
                 $iv = pack('H*', trim($matches[2]));
                 $symkey = pack('H*', md5($this->password . substr($iv, 0, 8)));
                 // symkey is short for symmetric key
                 $symkey .= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
                 $ciphertext = preg_replace('#.+(\\r|\\n|\\r\\n)\\1|[\\r\\n]|-.+-| #s', '', $key);
                 $ciphertext = preg_match('#^[a-zA-Z\\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false;
                 if ($ciphertext === false) {
                     $ciphertext = $key;
                 }
                 switch ($matches[1]) {
                     case 'AES-128-CBC':
                         $symkey = substr($symkey, 0, 16);
                         $crypto = new CryptAES();
                         break;
                     case 'DES-EDE3-CFB':
                         $crypto = new CryptTripleDES(CRYPT_DES_MODE_CFB);
                         break;
                     case 'DES-EDE3-CBC':
                         $crypto = new CryptTripleDES();
                         break;
                     case 'DES-CBC':
                         $crypto = new CryptDES();
                         break;
                     default:
                         return false;
                 }
                 $crypto->setKey($symkey);
                 $crypto->setIV($iv);
                 $decoded = $crypto->decrypt($ciphertext);
             } else {
                 $decoded = preg_replace('#-.+-|[\\r\\n]| #', '', $key);
                 $decoded = preg_match('#^[a-zA-Z\\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false;
             }
             if ($decoded !== false) {
                 $key = $decoded;
             }
             $components = array();
             if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
                 return false;
             }
             if ($this->_decodeLength($key) != strlen($key)) {
                 return false;
             }
             $tag = ord($this->_string_shift($key));
             /* intended for keys for which OpenSSL's asn1parse returns the following:
             
                 0:d=0  hl=4 l= 631 cons: SEQUENCE
                 4:d=1  hl=2 l=   1 prim:  INTEGER           :00
                 7:d=1  hl=2 l=  13 cons:  SEQUENCE
                 9:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
                 20:d=2  hl=2 l=   0 prim:   NULL
                 22:d=1  hl=4 l= 609 prim:  OCTET STRING */
             if ($tag == CRYPT_RSA_ASN1_INTEGER && substr($key, 0, 3) == "0") {
                 $this->_string_shift($key, 3);
                 $tag = CRYPT_RSA_ASN1_SEQUENCE;
             }
             if ($tag == CRYPT_RSA_ASN1_SEQUENCE) {
                 /* intended for keys for which OpenSSL's asn1parse returns the following:
                 
                       0:d=0  hl=4 l= 290 cons: SEQUENCE
                       4:d=1  hl=2 l=  13 cons:  SEQUENCE
                       6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
                       17:d=2  hl=2 l=   0 prim:   NULL
                       19:d=1  hl=4 l= 271 prim:  BIT STRING */
                 $this->_string_shift($key, $this->_decodeLength($key));
                 $tag = ord($this->_string_shift($key));
                 // skip over the BIT STRING / OCTET STRING tag
                 $this->_decodeLength($key);
                 // skip over the BIT STRING / OCTET STRING length
                 // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
                 //  unused bits in the final subsequent octet. The number shall be in the range zero to seven."
                 //  -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
                 if ($tag == CRYPT_RSA_ASN1_BITSTRING) {
                     $this->_string_shift($key);
                 }
                 if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
                     return false;
                 }
                 if ($this->_decodeLength($key) != strlen($key)) {
                     return false;
                 }
                 $tag = ord($this->_string_shift($key));
             }
             if ($tag != CRYPT_RSA_ASN1_INTEGER) {
                 return false;
             }
             $length = $this->_decodeLength($key);
             $temp = $this->_string_shift($key, $length);
             if (strlen($temp) != 1 || ord($temp) > 2) {
                 $components['modulus'] = new MathBigInteger($temp, 256);
                 $this->_string_shift($key);
                 // skip over CRYPT_RSA_ASN1_INTEGER
                 $length = $this->_decodeLength($key);
                 $components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new MathBigInteger($this->_string_shift($key, $length), 256);
                 return $components;
             }
             if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {
                 return false;
             }
             $length = $this->_decodeLength($key);
             $components['modulus'] = new MathBigInteger($this->_string_shift($key, $length), 256);
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['publicExponent'] = new MathBigInteger($this->_string_shift($key, $length), 256);
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['privateExponent'] = new MathBigInteger($this->_string_shift($key, $length), 256);
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['primes'] = array(1 => new MathBigInteger($this->_string_shift($key, $length), 256));
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['primes'][] = new MathBigInteger($this->_string_shift($key, $length), 256);
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['exponents'] = array(1 => new MathBigInteger($this->_string_shift($key, $length), 256));
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['exponents'][] = new MathBigInteger($this->_string_shift($key, $length), 256);
             $this->_string_shift($key);
             $length = $this->_decodeLength($key);
             $components['coefficients'] = array(2 => new MathBigInteger($this->_string_shift($key, $length), 256));
             if (!empty($key)) {
                 if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
                     return false;
                 }
                 $this->_decodeLength($key);
                 while (!empty($key)) {
                     if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
                         return false;
                     }
                     $this->_decodeLength($key);
                     $key = substr($key, 1);
                     $length = $this->_decodeLength($key);
                     $components['primes'][] = new MathBigInteger($this->_string_shift($key, $length), 256);
                     $this->_string_shift($key);
                     $length = $this->_decodeLength($key);
                     $components['exponents'][] = new MathBigInteger($this->_string_shift($key, $length), 256);
                     $this->_string_shift($key);
                     $length = $this->_decodeLength($key);
                     $components['coefficients'][] = new MathBigInteger($this->_string_shift($key, $length), 256);
                 }
             }
             return $components;
         case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
             $key = base64_decode(preg_replace('#^ssh-rsa | .+$#', '', $key));
             if ($key === false) {
                 return false;
             }
             $cleanup = substr($key, 0, 11) == "ssh-rsa";
             if (strlen($key) <= 4) {
                 return false;
             }
             extract(unpack('Nlength', $this->_string_shift($key, 4)));
             $publicExponent = new MathBigInteger($this->_string_shift($key, $length), -256);
             if (strlen($key) <= 4) {
                 return false;
             }
             extract(unpack('Nlength', $this->_string_shift($key, 4)));
             $modulus = new MathBigInteger($this->_string_shift($key, $length), -256);
             if ($cleanup && strlen($key)) {
                 if (strlen($key) <= 4) {
                     return false;
                 }
                 extract(unpack('Nlength', $this->_string_shift($key, 4)));
                 $realModulus = new MathBigInteger($this->_string_shift($key, $length), -256);
                 return strlen($key) ? false : array('modulus' => $realModulus, 'publicExponent' => $modulus);
             } else {
                 return strlen($key) ? false : array('modulus' => $modulus, 'publicExponent' => $publicExponent);
             }
             // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
             // http://en.wikipedia.org/wiki/XML_Signature
         // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
         // http://en.wikipedia.org/wiki/XML_Signature
         case CRYPT_RSA_PRIVATE_FORMAT_XML:
         case CRYPT_RSA_PUBLIC_FORMAT_XML:
             $this->components = array();
             $xml = xml_parser_create('UTF-8');
             xml_set_object($xml, $this);
             xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
             xml_set_character_data_handler($xml, '_data_handler');
             if (!xml_parse($xml, $key)) {
                 return false;
             }
             return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
             // from PuTTY's SSHPUBK.C
         // from PuTTY's SSHPUBK.C
         case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
             $components = array();
             $key = preg_split('#\\r\\n|\\r|\\n#', $key);
             $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
             if ($type != 'ssh-rsa') {
                 return false;
             }
             $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
             $publicLength = trim(preg_replace('#Public-Lines: (\\d+)#', '$1', $key[3]));
             $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
             $public = substr($public, 11);
             extract(unpack('Nlength', $this->_string_shift($public, 4)));
             $components['publicExponent'] = new MathBigInteger($this->_string_shift($public, $length), -256);
             extract(unpack('Nlength', $this->_string_shift($public, 4)));
             $components['modulus'] = new MathBigInteger($this->_string_shift($public, $length), -256);
             $privateLength = trim(preg_replace('#Private-Lines: (\\d+)#', '$1', $key[$publicLength + 4]));
             $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
             switch ($encryption) {
                 case 'aes256-cbc':
                     $symkey = '';
                     $sequence = 0;
                     while (strlen($symkey) < 32) {
                         $temp = pack('Na*', $sequence++, $this->password);
                         $symkey .= pack('H*', sha1($temp));
                     }
                     $symkey = substr($symkey, 0, 32);
                     $crypto = new CryptAES();
             }
             if ($encryption != 'none') {
                 $crypto->setKey($symkey);
                 $crypto->disablePadding();
                 $private = $crypto->decrypt($private);
                 if ($private === false) {
                     return false;
                 }
             }
             extract(unpack('Nlength', $this->_string_shift($private, 4)));
             if (strlen($private) < $length) {
                 return false;
             }
             $components['privateExponent'] = new MathBigInteger($this->_string_shift($private, $length), -256);
             extract(unpack('Nlength', $this->_string_shift($private, 4)));
             if (strlen($private) < $length) {
                 return false;
             }
             $components['primes'] = array(1 => new MathBigInteger($this->_string_shift($private, $length), -256));
             extract(unpack('Nlength', $this->_string_shift($private, 4)));
             if (strlen($private) < $length) {
                 return false;
             }
             $components['primes'][] = new MathBigInteger($this->_string_shift($private, $length), -256);
             $temp = $components['primes'][1]->subtract($this->one);
             $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
             $temp = $components['primes'][2]->subtract($this->one);
             $components['exponents'][] = $components['publicExponent']->modInverse($temp);
             extract(unpack('Nlength', $this->_string_shift($private, 4)));
             if (strlen($private) < $length) {
                 return false;
             }
             $components['coefficients'] = array(2 => new MathBigInteger($this->_string_shift($private, $length), -256));
             return $components;
     }
 }