首页 > 解决方案 > python中套接字的AES加密错误

问题描述

我正在尝试使用 TCP 套接字将加密消息从一台计算机发送到另一台计算机。服务器加密字符串,将其发送给客户端,客户端解密字符串并打印原始版本。但是,我不断在客户端收到此错误:

ValueError: IV must be 16 bytes long

服务器代码是:

import socket, hashlib, base64
from Crypto.Cipher import AES
from Crypto import Random

BLOCK_SIZE = 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

password = "sdfsdfJDFJDSF8sd9fs"

def encrypt(raw, password):
    private_key = hashlib.sha256(password.encode("utf-8")).digest()
    raw = pad(raw)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return base64.b64encode(iv + cipher.encrypt(raw))

def decrypt(enc, password):
    private_key = hashlib.sha256(password.encode("utf-8")).digest()
    enc = base64.b64decode(enc)
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[16:]))

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("192.168.1.150", 443))
s.listen(5)
print("\n\nListening...\n\n")
conn, addr = s.accept()
print("\n\nConnection from\n\n")
message="hello world"
data=encrypt(message, password)
s.send(data)

客户端代码为:

import socket, base64, hashlib
from Crypto.Cipher import AES
from Crypto import Random

BLOCK_SIZE = 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

password = "sdfsdfJDFJDSF8sd9fs"

def encrypt(raw, password):
    private_key = hashlib.sha256(password.encode("utf-8")).digest()
    raw = pad(raw)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return base64.b64encode(iv + cipher.encrypt(raw))

def decrypt(enc, password):
    private_key = hashlib.sha256(password.encode("utf-8")).digest()
    enc = base64.b64decode(enc)
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[16:]))

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.1.150", 443))
data=s.recv(1024)
shellcode_raw=decrypt(data, password)
print(shellcode_raw)

标签: pythonpython-3.xsocketsencryptionaes

解决方案


我想到了。我相信这是将字节转换为字符串的错误,但我不确定。我还将s.recv(1024)函数中的字节数增加到s.recv(4096)Here is the code。

服务器代码:

import base64
import hashlib
import socket
from Crypto import Random
from Crypto.Cipher import AES

class AESCipher(object):
    def __init__(self, key): 
        self.bs = AES.block_size
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw.encode()))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

string="super secure"
password="djknBDS89dHFS(*HFSD())"
enc_string=str(AESCipher(password).encrypt(string))
enc_string_2=AESCipher(password).encrypt(string)
dec_string=str(AESCipher(password).decrypt(enc_string_2))
print("This is the password " + password)
print("Decrypted string: " + string)
print("Encrypted string: " + enc_string)
print("Decrypted string (v2): " + str(dec_string))

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('192.168.1.150', 4444))
sock.listen(5)
print("Listening for connections...")

conn, addr = sock.accept()
conn.send(enc_string_2)
conn.close()

客户端代码:

import socket
import base64
from Crypto import Random
from Crypto.Cipher import AES
import hashlib

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.1.150', 4444))

class AESCipher(object):
    def __init__(self, key): 
        self.bs = AES.block_size
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw.encode()))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

password="djknBDS89dHFS(*HFSD())"
data=sock.recv(4096)
decoded=AESCipher(password).decrypt(data.decode('utf-8'))
print(str(decoded))
sock.close()

推荐阅读