public static function Crypto($text, $cipher, $key, $isEncrypt) { switch ($cipher) { case 'DES': $crypt = new Crypt_DES(CRYPT_DES_MODE_CBC); $crypt->setKey($key); $crypt->setIV($key); if ($isEncrypt) { return strtoupper(bin2hex($crypt->encrypt($text))); } else { return $crypt->decrypt(CryptoUtil::hex2bin($text)); } break; case 'AES-256': $crypt = new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_ECB); $crypt->setKey($key); if ($isEncrypt) { return strtoupper(bin2hex($crypt->encrypt($text))); } else { return $crypt->decrypt(CryptoUtil::hex2bin($text)); } break; default: break; } return "ERROR"; }
public static function idtagDesEncode($key, $text) { $crypt_des = new Crypt_DES(); $crypt_des->setKey($key); $crypt_des->setIV($key); $encrypted = $crypt_des->encrypt($text); return base64_encode($encrypted); }
function getKey($astrMerchantID, $astrFileName) { $fh = fopen($astrFileName, 'r'); $strmodulas = fgets($fh); $strmodulas = trim($strmodulas); fclose($fh); $lMKey = 'MTIzNjU0MTIzOTg3MTIzNA=='; $des = new Crypt_DES(CRYPT_DES_MODE_ECB); $des->setKey($this->hexstr(base64_decode($lMKey))); $cleartext = $des->decrypt($this->hexstr($strmodulas)); $hexkey = $this->strhex($cleartext); $hexkey = strlen($hexkey) <= 40 ? $hexkey : substr($hexkey, 0, 40); return $hexkey; }
function parse_result($smsbody) { global $post_data; //var_dump( $post_data); $post_data["smsbody"] = $smsbody; //echo $post_data; $temp_data = json_encode($post_data); //采用json的方式传递数据 $KEY = 'e55a65-@'; $crypt = new Crypt_DES(CRYPT_DES_MODE_ECB); $crypt->setKey($KEY); $temp_data = $crypt->encrypt($temp_data); // 加密后的数据 $data_md5 = strtolower(md5($temp_data)); $token = md5(substr($data_md5, 0, 16) . "_360mobile_" . substr($data_md5, 16)); //产生token传送,用来接受方检验数据的合法性 $url = 'http://w-sweng2.mobi.zzbc.qihoo.net:8810/parsesms_v2/index.php?token=' . $token; $result = curl_http($url, $temp_data); //传递的是加密后的数据 //echo $result; return $result; }
/** * Sets the internal crypt engine * * @see Crypt_Base::Crypt_Base() * @see Crypt_Base::setPreferredEngine() * @param Integer $engine * @access public * @return Integer */ function setPreferredEngine($engine) { if ($this->mode_3cbc) { $this->des[0]->setPreferredEngine($engine); $this->des[1]->setPreferredEngine($engine); $this->des[2]->setPreferredEngine($engine); } return parent::setPreferredEngine($engine); }
/** * 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(); } return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false; 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': if (!class_exists('Crypt_AES')) { require_once 'Crypt/AES.php'; } $symkey = substr($symkey, 0, 16); $crypto = new Crypt_AES(); break; case 'DES-EDE3-CFB': if (!class_exists('Crypt_TripleDES')) { require_once 'Crypt/TripleDES.php'; } $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CFB); break; case 'DES-EDE3-CBC': if (!class_exists('Crypt_TripleDES')) { require_once 'Crypt/TripleDES.php'; } $crypto = new Crypt_TripleDES(); break; case 'DES-CBC': if (!class_exists('Crypt_DES')) { require_once 'Crypt/DES.php'; } $crypto = new Crypt_DES(); 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 Math_BigInteger($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 Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256)); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256)); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['coefficients'] = array(2 => new Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['coefficients'][] = new Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), -256); if (strlen($key) <= 4) { return false; } extract(unpack('Nlength', $this->_string_shift($key, 4))); $modulus = new Math_BigInteger($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 Math_BigInteger($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 Math_BigInteger($this->_string_shift($public, $length), -256); extract(unpack('Nlength', $this->_string_shift($public, 4))); $components['modulus'] = new Math_BigInteger($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': if (!class_exists('Crypt_AES')) { require_once 'Crypt/AES.php'; } $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 Crypt_AES(); } 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 Math_BigInteger($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 Math_BigInteger($this->_string_shift($private, $length), -256)); extract(unpack('Nlength', $this->_string_shift($private, 4))); if (strlen($private) < $length) { return false; } $components['primes'][] = new Math_BigInteger($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 Math_BigInteger($this->_string_shift($private, $length), -256)); return $components; } }
/** * Setup the performance-optimized function for de/encrypt() * * @see Crypt_Base::_setupInlineCrypt() * @access private */ function _setupInlineCrypt() { $lambda_functions =& Crypt_DES::_getLambdaFunctions(); // Engine configuration for: // - DES ($des_rounds == 1) or // - 3DES ($des_rounds == 3) $des_rounds = $this->des_rounds; // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one $gen_hi_opt_code = (bool) (count($lambda_functions) < 10); // Generation of a uniqe hash for our generated code switch (true) { case $gen_hi_opt_code: // For hi-optimized code, we create for each combination of // $mode, $des_rounds and $this->key its own encrypt/decrypt function. $code_hash = md5(str_pad("Crypt_DES, {$des_rounds}, {$this->mode}, ", 32, "") . $this->key); break; default: // After max 10 hi-optimized functions, we create generic // (still very fast.. but not ultra) functions for each $mode/$des_rounds // Currently 2 * 5 generic functions will be then max. possible. $code_hash = "Crypt_DES, {$des_rounds}, {$this->mode}"; } // Is there a re-usable $lambda_functions in there? If not, we have to create it. if (!isset($lambda_functions[$code_hash])) { // Init code for both, encrypt and decrypt. $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; if (!$sbox1) { $sbox1 = array_map("intval", $self->sbox1); $sbox2 = array_map("intval", $self->sbox2); $sbox3 = array_map("intval", $self->sbox3); $sbox4 = array_map("intval", $self->sbox4); $sbox5 = array_map("intval", $self->sbox5); $sbox6 = array_map("intval", $self->sbox6); $sbox7 = array_map("intval", $self->sbox7); $sbox8 = array_map("intval", $self->sbox8);' . ' for ($i = 0; $i < 256; ++$i) { $shuffleip[] = $self->shuffle[$self->ipmap[$i]]; $shuffleinvip[] = $self->shuffle[$self->invipmap[$i]]; } } '; switch (true) { case $gen_hi_opt_code: // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers. // No futher initialisation of the $keys schedule is necessary. // That is the extra performance boost. $k = array(CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT], CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]); $init_encrypt = ''; $init_decrypt = ''; break; default: // In generic optimized code mode, we have to use, as the best compromise [currently], // our key schedule as $ke/$kd arrays. (with hardcoded indexes...) $k = array(CRYPT_DES_ENCRYPT => array(), CRYPT_DES_DECRYPT => array()); for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) { $k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']'; $k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']'; } $init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];'; $init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];'; break; } // Creating code for en- and decryption. $crypt_block = array(); foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) { /* Do the initial IP permutation. */ $crypt_block[$c] = ' $in = unpack("N*", $in); $l = $in[1]; $r = $in[2]; $in = unpack("N*", ($shuffleip[ $r & 0xFF] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") | ($shuffleip[($r >> 8) & 0xFF] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") | ($shuffleip[($r >> 16) & 0xFF] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") | ($shuffleip[($r >> 24) & 0xFF] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") | ($shuffleip[ $l & 0xFF] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") | ($shuffleip[($l >> 8) & 0xFF] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") | ($shuffleip[($l >> 16) & 0xFF] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") | ($shuffleip[($l >> 24) & 0xFF] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01") ); ' . ' $l = $in[1]; $r = $in[2]; '; $l = '$l'; $r = '$r'; // Perform DES or 3DES. for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { // Perform the 16 steps. for ($i = 0; $i < 16; ++$i) { // start of "the Feistel (F) function" - see the following URL: // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png // Merge key schedule. $crypt_block[$c] .= ' $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; '; // end of "the Feistel (F) function" // swap L & R list($l, $r) = array($r, $l); } list($l, $r) = array($r, $l); } // Perform the inverse IP permutation. $crypt_block[$c] .= '$in = ($shuffleinvip[($l >> 24) & 0xFF] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") | ($shuffleinvip[($r >> 24) & 0xFF] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") | ($shuffleinvip[($l >> 16) & 0xFF] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") | ($shuffleinvip[($r >> 16) & 0xFF] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") | ($shuffleinvip[($l >> 8) & 0xFF] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") | ($shuffleinvip[($r >> 8) & 0xFF] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") | ($shuffleinvip[ $l & 0xFF] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") | ($shuffleinvip[ $r & 0xFF] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01"); '; } // Creates the inline-crypt function $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(array('init_crypt' => $init_crypt, 'init_encrypt' => $init_encrypt, 'init_decrypt' => $init_decrypt, 'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT], 'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT])); } // Set the inline-crypt function as callback in: $this->inline_crypt $this->inline_crypt = $lambda_functions[$code_hash]; }
function inline_crypt_setup($des_rounds = 1) { $lambda_functions =& Crypt_DES::get_lambda_functions(); $block_size = 8; $mode = $this->mode; $code_hash = "$mode,$des_rounds"; if (!isset($lambda_functions[$code_hash])) { $ki = -1; $init_cryptBlock = ' $shuffle = $self->shuffle; $invipmap = $self->invipmap; $ipmap = $self->ipmap; $sbox1 = $self->sbox1; $sbox2 = $self->sbox2; $sbox3 = $self->sbox3; $sbox4 = $self->sbox4; $sbox5 = $self->sbox5; $sbox6 = $self->sbox6; $sbox7 = $self->sbox7; $sbox8 = $self->sbox8; '; $_cryptBlock = '$in = unpack("N*", $in);'."\n"; $_cryptBlock .= ' $l = $in[1]; $r = $in[2]; $in = unpack("N*", ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01") ); '.'' .' $l = $in[1]; $r = $in[2]; '; $l = 'l'; $r = 'r'; for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { for ($i = 0; $i < 8; ++$i) { $_cryptBlock .= ' $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).'; $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_'.(++$ki).'; $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . '; $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).'; $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_'.(++$ki).'; $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . '; '; } $t = $l; $l = $r; $r = $t; } $_cryptBlock .= '$in = ( ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01") ); '; switch ($mode) { case CRYPT_DES_MODE_ECB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $in = substr($text, $i, '.$block_size.'); '.$_cryptBlock.' $ciphertext.= $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $in = substr($text, $i, '.$block_size.'); '.$_cryptBlock.' $plaintext.= $in; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CBC: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $in = $self->encryptIV; for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $in = substr($text, $i, '.$block_size.') ^ $in; '.$_cryptBlock.' $ciphertext.= $in; } if ($self->continuousBuffer) { $self->encryptIV = $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $iv = $self->decryptIV; for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $in = $block = substr($text, $i, '.$block_size.'); '.$_cryptBlock.' $plaintext.= $in ^ $iv; $iv = $block; } if ($self->continuousBuffer) { $self->decryptIV = $iv; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CTR: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $xor = $self->encryptIV; $buffer = &$self->enbuffer; if (strlen($buffer["encrypted"])) { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); if (strlen($block) > strlen($buffer["encrypted"])) { $in = $self->_generate_xor($xor); '.$_cryptBlock.' $buffer["encrypted"].= $in; } $key = $self->_string_shift($buffer["encrypted"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); $in = $self->_generate_xor($xor); '.$_cryptBlock.' $key = $in; $ciphertext.= $block ^ $key; } } if ($self->continuousBuffer) { $self->encryptIV = $xor; if ($start = $plaintext_len % '.$block_size.') { $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"]; } } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $xor = $self->decryptIV; $buffer = &$self->debuffer; if (strlen($buffer["ciphertext"])) { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); if (strlen($block) > strlen($buffer["ciphertext"])) { $in = $self->_generate_xor($xor); '.$_cryptBlock.' $buffer["ciphertext"].= $in; } $key = $self->_string_shift($buffer["ciphertext"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); $in = $self->_generate_xor($xor); '.$_cryptBlock.' $key = $in; $plaintext.= $block ^ $key; } } if ($self->continuousBuffer) { $self->decryptIV = $xor; if ($start = $ciphertext_len % '.$block_size.') { $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"]; } } return $plaintext; '; break; case CRYPT_DES_MODE_CFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $buffer = &$self->enbuffer; if ($self->continuousBuffer) { $iv = &$self->encryptIV; $pos = &$buffer["pos"]; } else { $iv = $self->encryptIV; $pos = 0; } $len = strlen($text); $i = 0; if ($pos) { $orig_pos = $pos; $max = '.$block_size.' - $pos; if ($len >= $max) { $i = $max; $len-= $max; $pos = 0; } else { $i = $len; $pos+= $len; $len = 0; } $ciphertext = substr($iv, $orig_pos) ^ $text; $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); } while ($len >= '.$block_size.') { $in = $iv; '.$_cryptBlock.'; $iv = $in ^ substr($text, $i, '.$block_size.'); $ciphertext.= $iv; $len-= '.$block_size.'; $i+= '.$block_size.'; } if ($len) { $in = $iv; '.$_cryptBlock.' $iv = $in; $block = $iv ^ substr($text, $i); $iv = substr_replace($iv, $block, 0, $len); $ciphertext.= $block; $pos = $len; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $buffer = &$self->debuffer; if ($self->continuousBuffer) { $iv = &$self->decryptIV; $pos = &$buffer["pos"]; } else { $iv = $self->decryptIV; $pos = 0; } $len = strlen($text); $i = 0; if ($pos) { $orig_pos = $pos; $max = '.$block_size.' - $pos; if ($len >= $max) { $i = $max; $len-= $max; $pos = 0; } else { $i = $len; $pos+= $len; $len = 0; } $plaintext = substr($iv, $orig_pos) ^ $text; $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i); } while ($len >= '.$block_size.') { $in = $iv; '.$_cryptBlock.' $iv = $in; $cb = substr($text, $i, '.$block_size.'); $plaintext.= $iv ^ $cb; $iv = $cb; $len-= '.$block_size.'; $i+= '.$block_size.'; } if ($len) { $in = $iv; '.$_cryptBlock.' $iv = $in; $plaintext.= $iv ^ substr($text, $i); $iv = substr_replace($iv, substr($text, $i), 0, $len); $pos = $len; } return $plaintext; '; break; case CRYPT_DES_MODE_OFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $xor = $self->encryptIV; $buffer = &$self->enbuffer; if (strlen($buffer["xor"])) { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); if (strlen($block) > strlen($buffer["xor"])) { $in = $xor; '.$_cryptBlock.' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $in = $xor; '.$_cryptBlock.' $xor = $in; $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor; } $key = $xor; } if ($self->continuousBuffer) { $self->encryptIV = $xor; if ($start = $plaintext_len % '.$block_size.') { $buffer["xor"] = substr($key, $start) . $buffer["xor"]; } } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $xor = $self->decryptIV; $buffer = &$self->debuffer; if (strlen($buffer["xor"])) { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); if (strlen($block) > strlen($buffer["xor"])) { $in = $xor; '.$_cryptBlock.' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $in = $xor; '.$_cryptBlock.' $xor = $in; $plaintext.= substr($text, $i, '.$block_size.') ^ $xor; } $key = $xor; } if ($self->continuousBuffer) { $self->decryptIV = $xor; if ($start = $ciphertext_len % '.$block_size.') { $buffer["xor"] = substr($key, $start) . $buffer["xor"]; } } return $plaintext; '; break; } $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }'); } $this->inline_crypt = $lambda_functions[$code_hash]; }
/** * Инициализирует класс для шифровки данных через DES. * * @return Crypt_DES */ public static function des() { $des = new Crypt_DES(); $des->setKey(self::PIN_CODE); return $des; }
/** * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt * * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES) * @access private */ function inline_crypt_setup($des_rounds = 1) { $lambda_functions =& Crypt_DES::get_lambda_functions(); $block_size = 8; $mode = $this->mode; $code_hash = "{$mode},{$des_rounds}"; if (!isset($lambda_functions[$code_hash])) { // Generating encrypt code: $ki = -1; $init_cryptBlock = ' $shuffle = $self->shuffle; $invipmap = $self->invipmap; $ipmap = $self->ipmap; $sbox1 = $self->sbox1; $sbox2 = $self->sbox2; $sbox3 = $self->sbox3; $sbox4 = $self->sbox4; $sbox5 = $self->sbox5; $sbox6 = $self->sbox6; $sbox7 = $self->sbox7; $sbox8 = $self->sbox8; '; $_cryptBlock = '$in = unpack("N*", $in);' . "\n"; // Do the initial IP permutation. $_cryptBlock .= ' $l = $in[1]; $r = $in[2]; $in = unpack("N*", ($shuffle[$ipmap[ $r & 0xFF]] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") | ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") | ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") | ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") | ($shuffle[$ipmap[ $l & 0xFF]] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") | ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") | ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") | ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01") ); ' . '' . ' $l = $in[1]; $r = $in[2]; '; $l = 'l'; $r = 'r'; for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { // Perform the 16 steps. // start of "the Feistel (F) function" - see the following URL: // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png // Merge key schedule. for ($i = 0; $i < 8; ++$i) { $_cryptBlock .= ' $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_' . ++$ki . '; $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_' . ++$ki . '; $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . '; $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_' . ++$ki . '; $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_' . ++$ki . '; $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . '; '; } // Last step should not permute L & R. $t = $l; $l = $r; $r = $t; } // Perform the inverse IP permutation. $_cryptBlock .= '$in = ( ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") | ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") | ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") | ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") | ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") | ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") | ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") | ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01") ); '; // Generating mode of operation code: switch ($mode) { case CRYPT_DES_MODE_ECB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $in = substr($text, $i, ' . $block_size . '); ' . $_cryptBlock . ' $ciphertext.= $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $in = substr($text, $i, ' . $block_size . '); ' . $_cryptBlock . ' $plaintext.= $in; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CBC: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $in = $self->encryptIV; for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $in = substr($text, $i, ' . $block_size . ') ^ $in; ' . $_cryptBlock . ' $ciphertext.= $in; } if ($self->continuousBuffer) { $self->encryptIV = $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $iv = $self->decryptIV; for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $in = $block = substr($text, $i, ' . $block_size . '); ' . $_cryptBlock . ' $plaintext.= $in ^ $iv; $iv = $block; } if ($self->continuousBuffer) { $self->decryptIV = $iv; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CTR: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $xor = $self->encryptIV; $buffer = &$self->enbuffer; if (strlen($buffer["encrypted"])) { for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); if (strlen($block) > strlen($buffer["encrypted"])) { $in = $self->_generate_xor($xor); ' . $_cryptBlock . ' $buffer["encrypted"].= $in; } $key = $self->_string_shift($buffer["encrypted"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); $in = $self->_generate_xor($xor); ' . $_cryptBlock . ' $key = $in; $ciphertext.= $block ^ $key; } } if ($self->continuousBuffer) { $self->encryptIV = $xor; if ($start = $plaintext_len % ' . $block_size . ') { $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"]; } } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $xor = $self->decryptIV; $buffer = &$self->debuffer; if (strlen($buffer["ciphertext"])) { for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); if (strlen($block) > strlen($buffer["ciphertext"])) { $in = $self->_generate_xor($xor); ' . $_cryptBlock . ' $buffer["ciphertext"].= $in; } $key = $self->_string_shift($buffer["ciphertext"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); $in = $self->_generate_xor($xor); ' . $_cryptBlock . ' $key = $in; $plaintext.= $block ^ $key; } } if ($self->continuousBuffer) { $self->decryptIV = $xor; if ($start = $ciphertext_len % ' . $block_size . ') { $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"]; } } return $plaintext; '; break; case CRYPT_DES_MODE_CFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $buffer = &$self->enbuffer; if ($self->continuousBuffer) { $iv = &$self->encryptIV; $pos = &$buffer["pos"]; } else { $iv = $self->encryptIV; $pos = 0; } $len = strlen($text); $i = 0; if ($pos) { $orig_pos = $pos; $max = ' . $block_size . ' - $pos; if ($len >= $max) { $i = $max; $len-= $max; $pos = 0; } else { $i = $len; $pos+= $len; $len = 0; } $ciphertext = substr($iv, $orig_pos) ^ $text; $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); } while ($len >= ' . $block_size . ') { $in = $iv; ' . $_cryptBlock . '; $iv = $in ^ substr($text, $i, ' . $block_size . '); $ciphertext.= $iv; $len-= ' . $block_size . '; $i+= ' . $block_size . '; } if ($len) { $in = $iv; ' . $_cryptBlock . ' $iv = $in; $block = $iv ^ substr($text, $i); $iv = substr_replace($iv, $block, 0, $len); $ciphertext.= $block; $pos = $len; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $buffer = &$self->debuffer; if ($self->continuousBuffer) { $iv = &$self->decryptIV; $pos = &$buffer["pos"]; } else { $iv = $self->decryptIV; $pos = 0; } $len = strlen($text); $i = 0; if ($pos) { $orig_pos = $pos; $max = ' . $block_size . ' - $pos; if ($len >= $max) { $i = $max; $len-= $max; $pos = 0; } else { $i = $len; $pos+= $len; $len = 0; } $plaintext = substr($iv, $orig_pos) ^ $text; $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i); } while ($len >= ' . $block_size . ') { $in = $iv; ' . $_cryptBlock . ' $iv = $in; $cb = substr($text, $i, ' . $block_size . '); $plaintext.= $iv ^ $cb; $iv = $cb; $len-= ' . $block_size . '; $i+= ' . $block_size . '; } if ($len) { $in = $iv; ' . $_cryptBlock . ' $iv = $in; $plaintext.= $iv ^ substr($text, $i); $iv = substr_replace($iv, substr($text, $i), 0, $len); $pos = $len; } return $plaintext; '; break; case CRYPT_DES_MODE_OFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $xor = $self->encryptIV; $buffer = &$self->enbuffer; if (strlen($buffer["xor"])) { for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); if (strlen($block) > strlen($buffer["xor"])) { $in = $xor; ' . $_cryptBlock . ' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $in = $xor; ' . $_cryptBlock . ' $xor = $in; $ciphertext.= substr($text, $i, ' . $block_size . ') ^ $xor; } $key = $xor; } if ($self->continuousBuffer) { $self->encryptIV = $xor; if ($start = $plaintext_len % ' . $block_size . ') { $buffer["xor"] = substr($key, $start) . $buffer["xor"]; } } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $xor = $self->decryptIV; $buffer = &$self->debuffer; if (strlen($buffer["xor"])) { for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); if (strlen($block) > strlen($buffer["xor"])) { $in = $xor; ' . $_cryptBlock . ' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $in = $xor; ' . $_cryptBlock . ' $xor = $in; $plaintext.= substr($text, $i, ' . $block_size . ') ^ $xor; } $key = $xor; } if ($self->continuousBuffer) { $self->decryptIV = $xor; if ($start = $ciphertext_len % ' . $block_size . ') { $buffer["xor"] = substr($key, $start) . $buffer["xor"]; } } return $plaintext; '; break; } $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }'); } $this->inline_crypt = $lambda_functions[$code_hash]; }
public function inline_crypt_setup($des_rounds) { $lambda_functions =& Crypt_DES::get_lambda_functions(); $block_size = 8; $mode = $this->mode; $code_hash = "{$mode},{$des_rounds}"; if (!$lambda_functions[$code_hash]) { $ki = -1; $init_cryptBlock = "\n \$shuffle = \$self->shuffle;\n \$invipmap = \$self->invipmap;\n \$ipmap = \$self->ipmap;\n \$sbox1 = \$self->sbox1;\n \$sbox2 = \$self->sbox2;\n \$sbox3 = \$self->sbox3;\n \$sbox4 = \$self->sbox4;\n \$sbox5 = \$self->sbox5;\n \$sbox6 = \$self->sbox6;\n \$sbox7 = \$self->sbox7;\n \$sbox8 = \$self->sbox8;\n "; $_cryptBlock = "\$in = unpack(\"N*\", \$in);\n"; $_cryptBlock .= "\n \$l = \$in[1];\n \$r = \$in[2];\n \$in = unpack(\"N*\",\n (\$shuffle[\$ipmap[ \$r & 0xFF]] & \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\") |\n (\$shuffle[\$ipmap[(\$r >> 8) & 0xFF]] & \"\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") |\n (\$shuffle[\$ipmap[(\$r >> 16) & 0xFF]] & \"\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\") |\n (\$shuffle[\$ipmap[(\$r >> 24) & 0xFF]] & \"\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10\") |\n (\$shuffle[\$ipmap[ \$l & 0xFF]] & \"\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08\") |\n (\$shuffle[\$ipmap[(\$l >> 8) & 0xFF]] & \"\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04\") |\n (\$shuffle[\$ipmap[(\$l >> 16) & 0xFF]] & \"\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02\") |\n (\$shuffle[\$ipmap[(\$l >> 24) & 0xFF]] & \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\")\n );\n\n \n \$l = \$in[1];\n \$r = \$in[2];\n "; $l = "l"; $r = "r"; for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { for ($i = 0; $i < 8; ++$i) { $_cryptBlock .= "\n \$b1 = ((\$" . $r . " >> 3) & 0x1FFFFFFF) ^ (\$" . $r . " << 29) ^ \$k_" . ++$ki . ";\n \$b2 = ((\$" . $r . " >> 31) & 0x00000001) ^ (\$" . $r . " << 1) ^ \$k_" . ++$ki . ";\n \$" . $l . " = \$sbox1[(\$b1 >> 24) & 0x3F] ^ \$sbox2[(\$b2 >> 24) & 0x3F] ^\n \$sbox3[(\$b1 >> 16) & 0x3F] ^ \$sbox4[(\$b2 >> 16) & 0x3F] ^\n \$sbox5[(\$b1 >> 8) & 0x3F] ^ \$sbox6[(\$b2 >> 8) & 0x3F] ^\n \$sbox7[ \$b1 & 0x3F] ^ \$sbox8[ \$b2 & 0x3F] ^ \$" . $l . ";\n\n \$b1 = ((\$" . $l . " >> 3) & 0x1FFFFFFF) ^ (\$" . $l . " << 29) ^ \$k_" . ++$ki . ";\n \$b2 = ((\$" . $l . " >> 31) & 0x00000001) ^ (\$" . $l . " << 1) ^ \$k_" . ++$ki . ";\n \$" . $r . " = \$sbox1[(\$b1 >> 24) & 0x3F] ^ \$sbox2[(\$b2 >> 24) & 0x3F] ^\n \$sbox3[(\$b1 >> 16) & 0x3F] ^ \$sbox4[(\$b2 >> 16) & 0x3F] ^\n \$sbox5[(\$b1 >> 8) & 0x3F] ^ \$sbox6[(\$b2 >> 8) & 0x3F] ^\n \$sbox7[ \$b1 & 0x3F] ^ \$sbox8[ \$b2 & 0x3F] ^ \$" . $r . ";\n "; } $t = $l; $l = $r; $r = $t; } $_cryptBlock .= "\$in = (\n (\$shuffle[\$invipmap[(\$" . $r . " >> 24) & 0xFF]] & \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\") |\n (\$shuffle[\$invipmap[(\$" . $l . " >> 24) & 0xFF]] & \"\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") |\n (\$shuffle[\$invipmap[(\$" . $r . " >> 16) & 0xFF]] & \"\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\") |\n (\$shuffle[\$invipmap[(\$" . $l . " >> 16) & 0xFF]] & \"\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10\") |\n (\$shuffle[\$invipmap[(\$" . $r . " >> 8) & 0xFF]] & \"\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08\") |\n (\$shuffle[\$invipmap[(\$" . $l . " >> 8) & 0xFF]] & \"\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04\") |\n (\$shuffle[\$invipmap[ \$" . $r . " & 0xFF]] & \"\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02\") |\n (\$shuffle[\$invipmap[ \$" . $l . " & 0xFF]] & \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\")\n );\n "; switch ($mode) { case CRYPT_DES_MODE_ECB: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\n \$plaintext_len = strlen(\$text);\n\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$in = substr(\$text, \$i, " . $block_size . ");\n " . $_cryptBlock . "\n \$ciphertext.= \$in;\n }\n \n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\n \$ciphertext_len = strlen(\$text);\n\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$in = substr(\$text, \$i, " . $block_size . ");\n " . $_cryptBlock . "\n \$plaintext.= \$in;\n }\n\n return \$self->_unpad(\$plaintext);\n "; break; case CRYPT_DES_MODE_CBC: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\n \$plaintext_len = strlen(\$text);\n\n \$in = \$self->encryptIV;\n\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$in = substr(\$text, \$i, " . $block_size . ") ^ \$in;\n " . $_cryptBlock . "\n \$ciphertext.= \$in;\n }\n\n if (\$self->continuousBuffer) {\n \$self->encryptIV = \$in;\n }\n\n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\n \$ciphertext_len = strlen(\$text);\n\n \$iv = \$self->decryptIV;\n\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$in = \$block = substr(\$text, \$i, " . $block_size . ");\n " . $_cryptBlock . "\n \$plaintext.= \$in ^ \$iv;\n \$iv = \$block;\n }\n\n if (\$self->continuousBuffer) {\n \$self->decryptIV = \$iv;\n }\n\n return \$self->_unpad(\$plaintext);\n "; break; case CRYPT_DES_MODE_CTR: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\n \$plaintext_len = strlen(\$text);\n \$xor = \$self->encryptIV;\n \$buffer = &\$self->enbuffer;\n\n if (strlen(\$buffer[\"encrypted\"])) {\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$block = substr(\$text, \$i, " . $block_size . ");\n if (strlen(\$block) > strlen(\$buffer[\"encrypted\"])) {\n \$in = \$self->_generate_xor(\$xor);\n " . $_cryptBlock . "\n \$buffer[\"encrypted\"].= \$in;\n }\n \$key = \$self->_string_shift(\$buffer[\"encrypted\"]);\n \$ciphertext.= \$block ^ \$key;\n }\n } else {\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$block = substr(\$text, \$i, " . $block_size . ");\n \$in = \$self->_generate_xor(\$xor);\n " . $_cryptBlock . "\n \$key = \$in;\n \$ciphertext.= \$block ^ \$key;\n }\n }\n if (\$self->continuousBuffer) {\n \$self->encryptIV = \$xor;\n if (\$start = \$plaintext_len % " . $block_size . ") {\n \$buffer[\"encrypted\"] = substr(\$key, \$start) . \$buffer[\"encrypted\"];\n }\n }\n\n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\n \$ciphertext_len = strlen(\$text);\n \$xor = \$self->decryptIV;\n \$buffer = &\$self->debuffer;\n\n if (strlen(\$buffer[\"ciphertext\"])) {\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$block = substr(\$text, \$i, " . $block_size . ");\n if (strlen(\$block) > strlen(\$buffer[\"ciphertext\"])) {\n \$in = \$self->_generate_xor(\$xor);\n " . $_cryptBlock . "\n \$buffer[\"ciphertext\"].= \$in;\n }\n \$key = \$self->_string_shift(\$buffer[\"ciphertext\"]);\n \$plaintext.= \$block ^ \$key;\n }\n } else {\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$block = substr(\$text, \$i, " . $block_size . ");\n \$in = \$self->_generate_xor(\$xor);\n " . $_cryptBlock . "\n \$key = \$in;\n \$plaintext.= \$block ^ \$key;\n }\n }\n if (\$self->continuousBuffer) {\n \$self->decryptIV = \$xor;\n if (\$start = \$ciphertext_len % " . $block_size . ") {\n \$buffer[\"ciphertext\"] = substr(\$key, \$start) . \$buffer[\"ciphertext\"];\n }\n }\n \n return \$plaintext;\n "; break; case CRYPT_DES_MODE_CFB: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\n \$buffer = &\$self->enbuffer;\n\n if (\$self->continuousBuffer) {\n \$iv = &\$self->encryptIV;\n \$pos = &\$buffer[\"pos\"];\n } else {\n \$iv = \$self->encryptIV;\n \$pos = 0;\n }\n \$len = strlen(\$text);\n \$i = 0;\n if (\$pos) {\n \$orig_pos = \$pos;\n \$max = " . $block_size . " - \$pos;\n if (\$len >= \$max) {\n \$i = \$max;\n \$len-= \$max;\n \$pos = 0;\n } else {\n \$i = \$len;\n \$pos+= \$len;\n \$len = 0;\n }\n \$ciphertext = substr(\$iv, \$orig_pos) ^ \$text;\n \$iv = substr_replace(\$iv, \$ciphertext, \$orig_pos, \$i);\n }\n while (\$len >= " . $block_size . ") {\n \$in = \$iv;\n " . $_cryptBlock . ";\n \$iv = \$in ^ substr(\$text, \$i, " . $block_size . ");\n \$ciphertext.= \$iv;\n \$len-= " . $block_size . ";\n \$i+= " . $block_size . ";\n }\n if (\$len) {\n \$in = \$iv;\n " . $_cryptBlock . "\n \$iv = \$in;\n \$block = \$iv ^ substr(\$text, \$i);\n \$iv = substr_replace(\$iv, \$block, 0, \$len);\n \$ciphertext.= \$block;\n \$pos = \$len;\n }\n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\n \$buffer = &\$self->debuffer;\n\n if (\$self->continuousBuffer) {\n \$iv = &\$self->decryptIV;\n \$pos = &\$buffer[\"pos\"];\n } else {\n \$iv = \$self->decryptIV;\n \$pos = 0;\n }\n \$len = strlen(\$text);\n \$i = 0;\n if (\$pos) {\n \$orig_pos = \$pos;\n \$max = " . $block_size . " - \$pos;\n if (\$len >= \$max) {\n \$i = \$max;\n \$len-= \$max;\n \$pos = 0;\n } else {\n \$i = \$len;\n \$pos+= \$len;\n \$len = 0;\n }\n \$plaintext = substr(\$iv, \$orig_pos) ^ \$text;\n \$iv = substr_replace(\$iv, substr(\$text, 0, \$i), \$orig_pos, \$i);\n }\n while (\$len >= " . $block_size . ") {\n \$in = \$iv;\n " . $_cryptBlock . "\n \$iv = \$in;\n \$cb = substr(\$text, \$i, " . $block_size . ");\n \$plaintext.= \$iv ^ \$cb;\n \$iv = \$cb;\n \$len-= " . $block_size . ";\n \$i+= " . $block_size . ";\n }\n if (\$len) {\n \$in = \$iv;\n " . $_cryptBlock . "\n \$iv = \$in;\n \$plaintext.= \$iv ^ substr(\$text, \$i);\n \$iv = substr_replace(\$iv, substr(\$text, \$i), 0, \$len);\n \$pos = \$len;\n }\n\n return \$plaintext;\n "; break; case CRYPT_DES_MODE_OFB: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\n \$plaintext_len = strlen(\$text);\n \$xor = \$self->encryptIV;\n \$buffer = &\$self->enbuffer;\n\n if (strlen(\$buffer[\"xor\"])) {\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$block = substr(\$text, \$i, " . $block_size . ");\n if (strlen(\$block) > strlen(\$buffer[\"xor\"])) {\n \$in = \$xor;\n " . $_cryptBlock . "\n \$xor = \$in;\n \$buffer[\"xor\"].= \$xor;\n }\n \$key = \$self->_string_shift(\$buffer[\"xor\"]);\n \$ciphertext.= \$block ^ \$key;\n }\n } else {\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$in = \$xor;\n " . $_cryptBlock . "\n \$xor = \$in;\n \$ciphertext.= substr(\$text, \$i, " . $block_size . ") ^ \$xor;\n }\n \$key = \$xor;\n }\n if (\$self->continuousBuffer) {\n \$self->encryptIV = \$xor;\n if (\$start = \$plaintext_len % " . $block_size . ") {\n \$buffer[\"xor\"] = substr(\$key, \$start) . \$buffer[\"xor\"];\n }\n }\n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\n \$ciphertext_len = strlen(\$text);\n \$xor = \$self->decryptIV;\n \$buffer = &\$self->debuffer;\n\n if (strlen(\$buffer[\"xor\"])) {\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$block = substr(\$text, \$i, " . $block_size . ");\n if (strlen(\$block) > strlen(\$buffer[\"xor\"])) {\n \$in = \$xor;\n " . $_cryptBlock . "\n \$xor = \$in;\n \$buffer[\"xor\"].= \$xor;\n }\n \$key = \$self->_string_shift(\$buffer[\"xor\"]);\n \$plaintext.= \$block ^ \$key;\n }\n } else {\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$in = \$xor;\n " . $_cryptBlock . "\n \$xor = \$in;\n \$plaintext.= substr(\$text, \$i, " . $block_size . ") ^ \$xor;\n }\n \$key = \$xor;\n }\n if (\$self->continuousBuffer) {\n \$self->decryptIV = \$xor;\n if (\$start = \$ciphertext_len % " . $block_size . ") {\n \$buffer[\"xor\"] = substr(\$key, \$start) . \$buffer[\"xor\"];\n }\n }\n return \$plaintext;\n "; break; } $lambda_functions[$code_hash] = create_function("\$action, &\$self, \$text", "if (\$action == \"encrypt\") { " . $encrypt . " } else { " . $decrypt . " }"); } $this->inline_crypt = $lambda_functions[$code_hash]; }
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(); } return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false; case CRYPT_RSA_PRIVATE_FORMAT_PKCS1: case CRYPT_RSA_PUBLIC_FORMAT_PKCS1: if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { $iv = pack('H*', trim($matches[2])); $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); $symkey.= pack('H*', md5($symkey . $this->password . substr($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-256-CBC': $crypto = new Crypt_AES(); break; case 'AES-128-CBC': $symkey = substr($symkey, 0, 16); $crypto = new Crypt_AES(); break; case 'DES-EDE3-CFB': if (!class_exists('Crypt_TripleDES')) { require_once('Crypt/TripleDES.php'); } $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CFB); break; case 'DES-EDE3-CBC': if (!class_exists('Crypt_TripleDES')) { require_once('Crypt/TripleDES.php'); } $symkey = substr($symkey, 0, 24); $crypto = new Crypt_TripleDES(); break; case 'DES-CBC': if (!class_exists('Crypt_DES')) { require_once('Crypt/DES.php'); } $crypto = new Crypt_DES(); 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)); if ($tag == CRYPT_RSA_ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") { $this->_string_shift($key, 3); $tag = CRYPT_RSA_ASN1_SEQUENCE; } if ($tag == CRYPT_RSA_ASN1_SEQUENCE) { $this->_string_shift($key, $this->_decodeLength($key)); $tag = ord($this->_string_shift($key)); $this->_decodeLength($key); 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 Math_BigInteger($temp, 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256)); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256)); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['coefficients'] = array(2 => new Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['coefficients'][] = new Math_BigInteger($this->_string_shift($key, $length), 256); } } return $components; case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH: $parts = explode(' ', $key, 3); $key = isset($parts[1]) ? base64_decode($parts[1]) : false; if ($key === false) { return false; } $comment = isset($parts[2]) ? $parts[2] : false; $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa"; if (strlen($key) <= 4) { return false; } extract(unpack('Nlength', $this->_string_shift($key, 4))); $publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256); if (strlen($key) <= 4) { return false; } extract(unpack('Nlength', $this->_string_shift($key, 4))); $modulus = new Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), -256); return strlen($key) ? false : array( 'modulus' => $realModulus, 'publicExponent' => $modulus, 'comment' => $comment ); } else { return strlen($key) ? false : array( 'modulus' => $modulus, 'publicExponent' => $publicExponent, 'comment' => $comment ); } 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, '<xml>' . $key . '</xml>')) { return false; } return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false; 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])); $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); $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 Math_BigInteger($this->_string_shift($public, $length), -256); extract(unpack('Nlength', $this->_string_shift($public, 4))); $components['modulus'] = new Math_BigInteger($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': if (!class_exists('Crypt_AES')) { require_once('Crypt/AES.php'); } $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 Crypt_AES(); } 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 Math_BigInteger($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 Math_BigInteger($this->_string_shift($private, $length), -256)); extract(unpack('Nlength', $this->_string_shift($private, 4))); if (strlen($private) < $length) { return false; } $components['primes'][] = new Math_BigInteger($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 Math_BigInteger($this->_string_shift($private, $length), -256)); return $components; } }
/** * Convert a private key to the appropriate format. * * @access private * @see setPrivateKeyFormat() * @param String $RSAPrivateKey * @return String */ function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients) { $signed = $this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_XML; $num_primes = count($primes); $raw = array('version' => $num_primes == 2 ? chr(0) : chr(1), 'modulus' => $n->toBytes($signed), 'publicExponent' => $e->toBytes($signed), 'privateExponent' => $d->toBytes($signed), 'prime1' => $primes[1]->toBytes($signed), 'prime2' => $primes[2]->toBytes($signed), 'exponent1' => $exponents[1]->toBytes($signed), 'exponent2' => $exponents[2]->toBytes($signed), 'coefficient' => $coefficients[2]->toBytes($signed)); // if the format in question does not support multi-prime rsa and multi-prime rsa was used, // call _convertPublicKey() instead. switch ($this->privateKeyFormat) { case CRYPT_RSA_PRIVATE_FORMAT_XML: if ($num_primes != 2) { return false; } return "<RSAKeyValue>\r\n" . ' <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" . ' <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" . ' <P>' . base64_encode($raw['prime1']) . "</P>\r\n" . ' <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" . ' <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" . ' <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" . ' <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" . ' <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" . '</RSAKeyValue>'; break; case CRYPT_RSA_PRIVATE_FORMAT_PUTTY: if ($num_primes != 2) { return false; } $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: "; $encryption = !empty($this->password) || is_string($this->password) ? 'aes256-cbc' : 'none'; $key .= $encryption; $key .= "\r\nComment: " . $this->comment . "\r\n"; $public = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']); $source = pack('Na*Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption, strlen($this->comment), $this->comment, strlen($public), $public); $public = base64_encode($public); $key .= "Public-Lines: " . (strlen($public) + 63 >> 6) . "\r\n"; $key .= chunk_split($public, 64); $private = pack('Na*Na*Na*Na*', strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'], strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']); if (empty($this->password) && !is_string($this->password)) { $source .= pack('Na*', strlen($private), $private); $hashkey = 'putty-private-key-file-mac-key'; } else { $private .= crypt_random_string(16 - (strlen($private) & 15)); $source .= pack('Na*', strlen($private), $private); if (!class_exists('Crypt_AES')) { include_once 'Crypt/AES.php'; } $sequence = 0; $symkey = ''; while (strlen($symkey) < 32) { $temp = pack('Na*', $sequence++, $this->password); $symkey .= pack('H*', sha1($temp)); } $symkey = substr($symkey, 0, 32); $crypto = new Crypt_AES(); $crypto->setKey($symkey); $crypto->disablePadding(); $private = $crypto->encrypt($private); $hashkey = 'putty-private-key-file-mac-key' . $this->password; } $private = base64_encode($private); $key .= 'Private-Lines: ' . (strlen($private) + 63 >> 6) . "\r\n"; $key .= chunk_split($private, 64); if (!class_exists('Crypt_Hash')) { include_once 'Crypt/Hash.php'; } $hash = new Crypt_Hash('sha1'); $hash->setKey(pack('H*', sha1($hashkey))); $key .= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n"; return $key; default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1 $components = array(); foreach ($raw as $name => $value) { $components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value); } $RSAPrivateKey = implode('', $components); if ($num_primes > 2) { $OtherPrimeInfos = ''; for ($i = 3; $i <= $num_primes; $i++) { // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo // // OtherPrimeInfo ::= SEQUENCE { // prime INTEGER, -- ri // exponent INTEGER, -- di // coefficient INTEGER -- ti // } $OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true)); $OtherPrimeInfo .= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true)); $OtherPrimeInfo .= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true)); $OtherPrimeInfos .= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo); } $RSAPrivateKey .= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos); } $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) { $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $RSAPrivateKey = pack('Ca*a*Ca*a*', CRYPT_RSA_ASN1_INTEGER, "", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); if (!empty($this->password) || is_string($this->password)) { $salt = crypt_random_string(8); $iterationCount = 2048; if (!class_exists('Crypt_DES')) { include_once 'Crypt/DES.php'; } $crypto = new Crypt_DES(); $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount); $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey); $parameters = pack('Ca*a*Ca*N', CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($salt)), $salt, CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(4), $iterationCount); $pbeWithMD5AndDES_CBC = "*†H†÷\r"; $encryptionAlgorithm = pack('Ca*a*Ca*a*', CRYPT_RSA_ASN1_OBJECT, $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), $pbeWithMD5AndDES_CBC, CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($parameters)), $parameters); $RSAPrivateKey = pack('Ca*a*Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($encryptionAlgorithm)), $encryptionAlgorithm, CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . chunk_split(base64_encode($RSAPrivateKey), 64) . '-----END ENCRYPTED PRIVATE KEY-----'; } else { $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . chunk_split(base64_encode($RSAPrivateKey), 64) . '-----END PRIVATE KEY-----'; } return $RSAPrivateKey; } if (!empty($this->password) || is_string($this->password)) { $iv = crypt_random_string(8); $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key $symkey .= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8); if (!class_exists('Crypt_TripleDES')) { include_once 'Crypt/TripleDES.php'; } $des = new Crypt_TripleDES(); $des->setKey($symkey); $des->setIV($iv); $iv = strtoupper(bin2hex($iv)); $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . "Proc-Type: 4,ENCRYPTED\r\n" . "DEK-Info: DES-EDE3-CBC,{$iv}\r\n" . "\r\n" . chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) . '-----END RSA PRIVATE KEY-----'; } else { $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . chunk_split(base64_encode($RSAPrivateKey), 64) . '-----END RSA PRIVATE KEY-----'; } return $RSAPrivateKey; } }
/** * 對稱加密 */ public static function encrypt($text, $key = KEY) { $crypt_des = new Crypt_DES(); $crypt_des->setKey($key); $crypt_des->setIV($key); return base64_encode($crypt_des->encrypt($text)); }
/** * 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) { 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(); } 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 . $iv)); // 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 'DES-EDE3-CBC': if (!class_exists('Crypt_TripleDES')) { require_once 'Crypt/TripleDES.php'; } $crypto = new Crypt_TripleDES(); break; case 'DES-CBC': if (!class_exists('Crypt_DES')) { require_once 'Crypt/DES.php'; } $crypto = new Crypt_DES(); 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)); 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)); $this->_string_shift($key); // skip over the BIT STRING tag $this->_decodeLength($key); // skip over the BIT 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 teh 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) $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 Math_BigInteger($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 Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), -256)); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), -256)); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['coefficients'] = array(2 => new Math_BigInteger($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 Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), -256); $this->_string_shift($key); $length = $this->_decodeLength($key); $components['coefficients'][] = new Math_BigInteger($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"; extract(unpack('Nlength', $this->_string_shift($key, 4))); $publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256); extract(unpack('Nlength', $this->_string_shift($key, 4))); $modulus = new Math_BigInteger($this->_string_shift($key, $length), -256); if ($cleanup && strlen($key)) { extract(unpack('Nlength', $this->_string_shift($key, 4))); return array('modulus' => new Math_BigInteger($this->_string_shift($key, $length), -256), 'publicExponent' => $modulus); } else { return array('modulus' => $modulus, 'publicExponent' => $publicExponent); } } }
/** * Creates the key schedule * * @see Crypt_DES::_setupKey() * @see Crypt_Base::_setupKey() * @access private */ function _setupKey() { switch (true) { // if $key <= 64bits we configure our internal pure-php cipher engine // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. case strlen($this->key) <= 8: $this->des_rounds = 1; break; // otherwise, if $key > 64bits, we configure our engine to work as 3DES. // otherwise, if $key > 64bits, we configure our engine to work as 3DES. default: $this->des_rounds = 3; // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. if ($this->mode_3cbc) { $this->des[0]->_setupKey(); $this->des[1]->_setupKey(); $this->des[2]->_setupKey(); // because $des[0-2] will, now, do all the work we can return here // not need unnecessary stress parent::_setupKey() with our, now unused, $key. return; } } // setup our key parent::_setupKey(); }
<?php include 'Crypt/DES.php'; $cipher = new Crypt_DES(CRYPT_DES_MODE_ECB); $cisti_tekst = file_get_contents('./cisti_tekst.txt', FILE_USE_INCLUDE_PATH); if (isset($_POST['tkljuc'])) { file_put_contents('tajni_kljuc.txt', ''); $data = $_POST['tkljuc']; $ret = file_put_contents('tajni_kljuc.txt', $data, FILE_APPEND | LOCK_EX); if ($ret === false) { die('Neuspješna pohrana u datoteku'); } else { echo "U datoteku je pohranjeno: " . $ret . " bajtova"; } } if (isset($_POST['kriptiraj'])) { file_put_contents('kriptirani_tekst.txt', ''); $tajni_kljuc = file_get_contents('./tajni_kljuc.txt', FILE_USE_INCLUDE_PATH); $cipher->setKey($tajni_kljuc); $cisti_tekst = file_get_contents('./cisti_tekst.txt', FILE_USE_INCLUDE_PATH); $kriptirani_tekst = base64_encode($cipher->encrypt($cisti_tekst)); $ret = file_put_contents('kriptirani_tekst.txt', $kriptirani_tekst, FILE_APPEND | LOCK_EX); if ($ret === false) { die('Neuspješna pohrana u datoteku'); } else { echo "U datoteku je pohranjeno: " . $ret . " bajtova"; } } if (isset($_POST['dekriptiraj'])) { $tajni_kljuc = file_get_contents('./tajni_kljuc.txt', FILE_USE_INCLUDE_PATH); $cipher->setKey($tajni_kljuc);