Discuz authcode classic PHP encryption decryption function parsing

  • 2020-03-31 20:25:03
  • OfStack

The principle is as follows:
encryption
Plaintext: 1010 1001
Key: 1110 0011
Ciphertext: 0100 1010
Get the ciphertext 0100 1010, decryption needs and key different or under it
decryption
Ciphertext: 0100 1010
Key: 1110 0011
Plaintext: 1010 1001
There's no fancy algorithm, keys are very important, so it's all about generating keys.
Shall we take a look at the authcode of kangsheng together

//Parameter interpretation
//$string: plaintext or ciphertext
//$operation: DECODE means decryption and DECODE means encryption
//$key: a key
//$expiry: term of validity of ciphertext
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { 
//Dynamic key length, the same plaintext will generate different ciphertext depending on the dynamic key
$ckey_length = 4; 

//The key
$key = md5($key ? $key : $GLOBALS['discuz_auth_key']); 

//Key a will participate in encryption and decryption
$keya = md5(substr($key, 0, 16)); 
//Key b will be used for data integrity verification
$keyb = md5(substr($key, 16, 16)); 
//Key c is used to change the generated ciphertext
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): 
substr(md5(microtime()), -$ckey_length)) : ''; 
//The key that participates in the operation
$cryptkey = $keya.md5($keya.$keyc); 
$key_length = strlen($cryptkey); 
//Plaintext, the first 10 bits to save the timestamp, decryption to verify the validity of the data, 10 to 26 bits to save $keyb(keyb), decryption to verify the integrity of the data
//If you are decoding, you start with the $ckey_length bit, because the $ckey_length bit before the ciphertext holds the dynamic key to ensure correct decryption
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : 
sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; 
$string_length = strlen($string); 
$result = ''; 
$box = range(0, 255); 
$rndkey = array(); 
//Generate the keybook
for($i = 0; $i <= 255; $i++) { 
$rndkey[$i] = ord($cryptkey[$i % $key_length]); 
} 
//Using a fixed algorithm to mess up the keybook and add randomness seems complicated, but it doesn't actually increase the strength of the ciphertext
for($j = $i = 0; $i < 256; $i++) { 
$j = ($j + $box[$i] + $rndkey[$i]) % 256; 
$tmp = $box[$i]; 
$box[$i] = $box[$j]; 
$box[$j] = $tmp; 
} 
//Core encryption and decryption
for($a = $j = $i = 0; $i < $string_length; $i++) { 
$a = ($a + 1) % 256; 
$j = ($j + $box[$a]) % 256; 
$tmp = $box[$a]; 
$box[$a] = $box[$j]; 
$box[$j] = $tmp; 
//From the keybook the key is xor and then converted to a character
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); 
} 
if($operation == 'DECODE') { 
//Substr ($result, 0, 10) == 0 to validate the data
//Substr ($result, 0, 10) -time ()> 0 validate the data
//Substr ($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) verifies data integrity
//To verify the validity of the data, see the format of the unencrypted plaintext
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && 
substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { 
return substr($result, 26); 
} else { 
return ''; 
} 
} else { 
//Keep the dynamic key in the ciphertext, which is why the same plaintext can be decrypted after producing different ciphertext
//Because the encrypted ciphertext may be some special characters, the replication process may be lost, so base64 encoding
return $keyc.str_replace('=', '', base64_encode($result)); 
} 
} 

Related articles: