PHP暗号解読アルゴリズムauthcodeをPythonで書き換える
Discuzシリーズの製品で広く使われている暗号解読アルゴリズムauthcodeを一度読んだばかりで、利益が得られ、巧みに設計されています.
その中の考えを本当に理解するために、Pythonで書き直しました.白プログラマーは1枚で、学芸が精巧ではありません.通りかかった大侠の皆さんがもっと教えてくれることを望んでいます.
PS:法的な面では,元のアルゴリズムの使用が制限されているかどうかは不明である.原文:CatRollスタジオ
Pythonコード:
PHPコード:
その中の考えを本当に理解するために、Pythonで書き直しました.白プログラマーは1枚で、学芸が精巧ではありません.通りかかった大侠の皆さんがもっと教えてくれることを望んでいます.
PS:法的な面では,元のアルゴリズムの使用が制限されているかどうかは不明である.原文:CatRollスタジオ
Pythonコード:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
import base64
import hashlib
class AuthCode(object):
@classmethod
def encode(cls, string, key, expiry=0):
"""
@param string:
@param key:
@return:
"""
return cls._auth_code(string, 'ENCODE', key, expiry)
@classmethod
def decode(cls, string, key, expiry=0):
"""
@param string:
@param key:
@return:
"""
return cls._auth_code(string, 'DECODE', key, expiry)
@staticmethod
def _md5(source_string):
return hashlib.md5(source_string).hexdigest()
@classmethod
def _auth_code(cls, input_string, operation='DECODE', key='', expiry=3600):
"""
/
@param input_string:
@param operation: ( , )
@param key:
@param expiry: , ,0
@return: base64_encode
"""
# ----------------------- -----------------------
rand_key_length = 4
# 0-32
# , , ,
# , , = 16 ckey_length , 0,
key = cls._md5(key)
key_a = cls._md5(key[:16])
key_b = cls._md5(key[16:])
if rand_key_length:
if operation == 'DECODE':
key_c = input_string[:rand_key_length]
else:
key_c = cls._md5(str(time.time()))[-rand_key_length:]
else:
key_c = ''
crypt_key = key_a + cls._md5(key_a + key_c)
if operation == 'DECODE':
handled_string = base64.b64decode(input_string[rand_key_length:])
else:
expiration_time = expiry + int(time.time) if expiry else 0
handled_string = '%010d' % expiration_time + cls._md5(input_string + key_b)[:16] + input_string
rand_key = list()
for i in xrange(256):
rand_key.append(ord(crypt_key[i % len(crypt_key)]))
# ----------------------------------------------------------
box = range(256)
j = 0
for i in xrange(256):
j = (j + box[i] + rand_key[i]) % 256
tmp = box[i]
box[i] = box[j]
box[j] = tmp
#for i in xrange(len(box)):
# print str(box[i]).rjust(5),
# if ((i + 1) % 10) == 0:
# print ''
result = ''
a = 0
j = 0
for i in xrange(len(handled_string)):
a = (a + 1) % 256
j = (j + box[a]) % 256
tmp = box[a]
box[a] = box[j]
box[j] = tmp
result += chr(ord(handled_string[i])^(box[(box[a]+box[j])%256]))
if operation == 'DECODE':
if (int(result[:10]) == 0 or (int(result[:10]) - time.time() > 0)) and \
(result[10:26] == cls._md5(result[26:] + key_b)[:16]):
output_string = result[26:]
else:
output_string = ''
else:
output_string = key_c + base64.b64encode(result)
return output_string
if __name__ == '__main__':
src = 'My name is Hu Ang, I\'m a programmer.'
key = 'fr1e54b8t4n4m47'
encoded_string = AuthCode.encode(src, key)
decoded_string = AuthCode.decode(encoded_string, key)
print 'Source String:', src
print 'After Encode :', encoded_string
print 'After Decode :', decoded_string
print '----------------------------------------------'
# PHP , Python
# $source_string = "My name is Hu Ang.";
# $secret_key = 'fr1e54b8t4n4m47';
# $encoded_string = authcode($source_string, 'ENCODE', $secret_key, 0);
php_encoded_string = '82798mEQ6ouQo1rFrbSXT5EHVjZ0gH0WuuZDXd9us/q44JAhmPwBAFZqvwXhvnjgUOJ+5aYh5ed8zNL3cjTOGBY='
print 'Decode string encoded via php:', AuthCode.decode(php_encoded_string, key)
# PS:Python PHP 。
PHPコード:
<?php
class AuthCode {
public static function encode($str, $key) {
return self::_auth_code($str, 'ENCODE', $key, 0);
}
public static function decode($str, $key) {
return self::_auth_code($str, 'DECODE', $key, 0);
}
public static function _auth_code($string, $operation = 'DECODE', $key = '', $expiry = 3600) {
/***
* 0-32;
* , , , , 。
* , , = 16 $ckey_length
* 0 ,
*/
$ckey_length = 4;
$key = md5($key);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$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();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
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;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
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 {
return $keyc.base64_encode($result);
}
}
}
$source_string = "My name is Hu Ang, I'm a programmer.";
$secret_key = 'fr1e54b8t4n4m47';
echo 'Source String: ' . $source_string . "
";
$encoded_string = AuthCode::encode($source_string, $secret_key);
echo 'After Encode : ' . $encoded_string . "
";
$decoded_string = AuthCode::decode($encoded_string, $secret_key);
echo 'After Decode : ' . $decoded_string . "
";
echo "----------------------------------------------
";
$python_encoded_string = "88fcnCU6Wb+6LPREpYrhB3NcKS3OU+V8FqQ4uUklvZR170HWlyBLtPKEtP9Ui/qZp1ZqEhF9f5k6XBDixsVgEKk=";
echo 'Decode string encoded via python: ' . AuthCode::decode($python_encoded_string, $secret_key);