我一直在玩python的加密库,我构建了一个简单的线程服务器来加密和解密。我遇到的问题是大约有三分之一的解密错误地回来了。这是代码:
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
global KEY
request_text = ''
while request_text.rfind("\n") == -1:
sock_data='';
recv_size=8192
sock_data=self.request.recv(recv_size)
if sock_data == '':
print "hangup"
break
request_text = request_text + sock_data
args = json.loads(request_text)
print request_text
print "\n"
if args['command'] == 'encrypt':
iv = Random.new().read(AES.block_size)
cipher = AES.new(KEY, AES.MODE_CFB, iv)
crypted_message = iv + b'|' + cipher.encrypt(unquote_plus(args['message']))
response = {'encrypted_message': binascii.hexlify(crypted_message)}
if args['command'] == 'decrypt':
unhexed = binascii.unhexlify(args['message'])
components = unhexed.split('|')
iv = components[0]
cipher = AES.new(KEY, AES.MODE_CFB, iv)
decrypted_message = cipher.decrypt(components[1])
response = {'decrypted_message': decrypted_message}
self.request.sendall(json.dumps(response) + "\n")
通常,我从python中得到这个错误:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/SocketServer.py", line 582, in process_request_thread
self.finish_request(request, client_address)
File "/usr/local/lib/python2.7/SocketServer.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/local/lib/python2.7/SocketServer.py", line 639, in __init__
self.handle()
File "cryptoserver.py", line 40, in handle
cipher = AES.new(KEY, AES.MODE_CFB, iv)
File "build/bdist.macosx-10.4-x86_64/egg/Crypto/Cipher/AES.py", line 95, in new
return AESCipher(key, *args, **kwargs)
File "build/bdist.macosx-10.4-x86_64/egg/Crypto/Cipher/AES.py", line 59, in __init__
blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
File "build/bdist.macosx-10.4-x86_64/egg/Crypto/Cipher/blockalgo.py", line 141, in __init__
self._cipher = factory.new(key, *args, **kwargs)
ValueError: IV must be 16 bytes long
----------------------------------------
但同样经常,我没有错误,但解密无法正常工作。我正在使用这个php来测试它:
<?php
include_once("config.php");
function encrypt($text) {
$package = array("command" => "encrypt",
"message" => base64_encode($text));
$package_json = json_encode($package);
$serverSays = transmit($package_json);
$serverSaysArray = json_decode($serverSays);
return $serverSaysArray->encrypted_message;
}
function decrypt($text) {
$package = array("command" => "decrypt",
"message" => $text);
$package_json = json_encode($package);
$serverSays = transmit($package_json);
$serverSaysArray = json_decode($serverSays);
return base64_decode($serverSaysArray->decrypted_message);
}
function transmit($package) {
global $CRYPTO_PORT;
global $CRYPTO_HOST;
$serverLink = fsockopen($CRYPTO_HOST, $CRYPTO_PORT);
if ($serverLink === FALSE) {
error_log("Could not connect to encryption server");
return FALSE;
}
fwrite($serverLink, $package . "\n");
$response = '';
while (!feof($serverLink)) {
$response .= fgets($serverLink, 128);
}
fclose($serverLink);
return $response;
}
while (TRUE) {
$enc = encrypt('totsadaddywoopxxx');
print "$enc\n";
$dec = decrypt($enc);
print "$dec\n";
$enc = encrypt('totsadaddywoopxxx');
print "$enc\n";
$dec = decrypt($enc);
print "$dec\n";
$enc = encrypt('totsadaddywoopxxx');
print "$enc\n";
$dec = decrypt($enc);
print "$dec\n";
#print decrypt('1c6dee677126551fa4b3f0732986dc3b7c985c64c07075e3651213d7a69435bcd87083e729e8de860c');
#print "\n";
#print decrypt('550cbec7498371dc01bcd6b88fc623b47cb2efd1881da6e07ee992229308305992bbc7ccc374f00c91d56d10a68d6110e2');
print "===========================\n";
sleep(1);
}
答案 0 :(得分:1)
在您的解密例程中,您使用:
unhexed.split('|')
找到IV和密文之间的边界。但是,IV是由发送者随机生成的。有时,它的16个字节中的一个将是124,即边界字符“|”。
当发生这种情况时(大约6%的情况),解密例程将使用
初始化密码在解密例程中你应该改为:
components = [ unhexed[:AES.block_size], unhexed[AES.block_size+1:] ]
或者你可以摆脱'|'分离器。