Портирование класса AES с Python 2.7 на 3.x + - PullRequest
0 голосов
/ 01 ноября 2019

Здравствуйте, любая помощь при переносе этого класса AES с Python 2.7 на 3.6+ будет принята с благодарностью.

У меня есть рабочая копия в Python 2.7 ниже, которую я реализовал нормально.

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


class AESHandler:
    def __init__(self, cipherKey):
        hashedKey = hashlib.sha1(); hashedKey.update(cipherKey)
        self.pad = lambda self, s: s + (self.blockSize - len(s) % self.blockSize) * "\x00"
        self.unPad = lambda self, s : s.rstrip('\x00')
        self.toHex = lambda self, x:"".join([hex(ord(c))[2:].zfill(2) for c in x])
        self.blockSize = 16
        self.cipherKey = hashedKey.hexdigest()[:32]



    def aes_encrypt(self, stringIn):
        stringIn = self.pad(self, stringIn)
        initVector = Random.new().read(AES.block_size)
        cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
        return self.toHex(self, initVector + cipher.encrypt(stringIn))



    def aes_decrypt(self, stringIn):
        stringIn = (stringIn).decode("hex_codec")
        initVector = stringIn[:16]
        cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
        return self.unPad(self, cipher.decrypt(stringIn[16:]))



dataIn  = "Hello World!"
aesHandler = AESHandler("SUPER_SECRET_KEY")

encodedString = aesHandler.aes_encrypt(dataIn)
print("EncodedString: " + encodedString)

decodedString = aesHandler.aes_decrypt(encodedString)
print("DecodedString: " + decodedString)

Первая проблема, которую заподозрили при попытке запустить класс в Python 3.6, - это ошибки кодирования. Поэтому я применил кодировку UTF-8 к простой текстовой строке и ключу шифрования, что привело к новым ошибкам.

1-я ошибка

Traceback (most recent call last):
  File "AESHandler.py", line 36, in <module>
    aesHandler = AESHandler("SUPER_SECRET_KEY")
  File "AESHandler.py", line 10, in __init__
    hashedKey = hashlib.sha1(); hashedKey.update(cipherKey)
TypeError: Unicode-objects must be encoded before hashing

В этот момент я добавил кодировку UTF-8 в строку открытого текста и ключ шифрования, чтобы исправить эту проблему, которая привела к следующей ошибке.

2-я ошибка

Traceback (most recent call last):
  File "AESHandler.py", line 38, in <module>
    encodedString = aesHandler.aes_encrypt(dataIn)
  File "AESHandler.py", line 20, in aes_encrypt
    stringIn = self.pad(self, stringIn)
  File "AESHandler.py", line 11, in <lambda>
    self.pad = lambda self, s: s + (self.blockSize - len(s) % self.blockSize) * "\x00"
TypeError: can't concat str to bytes

Чтобы исправить эту ошибку, я изменил:

self.pad = lambda self, s: s + (self.blockSize - len(s) % self.blockSize) * "\x00"

Изменено на:

self.pad = lambda self, s: s + ((self.blockSize - len(s) % self.blockSize) * "\x00").encode("UTF-8")

3-я ошибка

Traceback (most recent call last):
  File "AESHandler.py", line 38, in <module>
    encodedString = aesHandler.aes_encrypt(dataIn)
  File "AESHandler.py", line 22, in aes_encrypt
    cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/AES.py", line 232, in new
    return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/__init__.py", line 79, in _create_cipher
    return modes[mode](factory, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/_mode_cbc.py", line 274, in _create_cbc_cipher
    cipher_state = factory._create_base_cipher(kwargs)
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Cipher/AES.py", line 103, in _create_base_cipher
    result = start_operation(c_uint8_ptr(key),
  File "/usr/local/lib/python3.6/dist-packages/Crypto/Util/_raw_api.py", line 145, in c_uint8_ptr
    raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type <class 'str'> cannot be passed to C code

На данный момент я даже не очень хорошо понимаю ошибку или в каком направлении идти, чтобы это исправить. Ниже я оставил обновленный источник до этого момента. Любая помощь, чтобы понять и исправить это было бы здорово, спасибо!

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


class AESHandler:
    def __init__(self, cipherKey):
        hashedKey = hashlib.sha1(); hashedKey.update(cipherKey)
        self.pad = lambda self, s: s + (self.blockSize - len(s) % self.blockSize) * "\x00"
        self.unPad = lambda self, s : s.rstrip('\x00')
        self.toHex = lambda self, x:"".join([hex(ord(c))[2:].zfill(2) for c in x])
        self.blockSize = 16
        self.cipherKey = hashedKey.hexdigest()[:32]



    def aes_encrypt(self, stringIn):
        stringIn = self.pad(self, stringIn)
        initVector = Random.new().read(AES.block_size)
        cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
        return self.toHex(self, initVector + cipher.encrypt(stringIn))



    def aes_decrypt(self, stringIn):
        stringIn = (stringIn).decode("hex_codec")
        initVector = stringIn[:16]
        cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
        return self.unPad(self, cipher.decrypt(stringIn[16:]))



dataIn  = "Hello World!"
aesHandler = AESHandler("SUPER_SECRET_KEY")

encodedString = aesHandler.aes_encrypt(dataIn)
print("EncodedString: " + encodedString)

decodedString = aesHandler.aes_decrypt(encodedString)
print("DecodedString: " + decodedString)

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

Исправлено, было еще 2 строки, которые нужно было закодировать. Большое спасибо за помощь, ребята, ниже я опубликовал окончательную рабочую копию.

import hashlib
import codecs
from Crypto import Random
from Crypto.Cipher import AES


class AESHandler:
    def __init__(self, cipherKey):
        hashedKey = hashlib.sha1(); hashedKey.update(cipherKey.encode())
        self.pad = lambda self, s: s + (self.blockSize - len(s) % self.blockSize) * b'\x00'
        self.unPad = lambda self, s : s.rstrip(b'\x00')
        self.toHex = lambda self, x: b"".join([hex(c)[2:].zfill(2).encode() for c in x])
        self.blockSize = 16
        self.cipherKey = hashedKey.hexdigest()[:32]

    def aes_encrypt(self, stringIn):
        stringIn = self.pad(self, stringIn.encode())
        initVector = Random.new().read(AES.block_size)
        cipher = AES.new(self.cipherKey.encode(), AES.MODE_CBC, initVector)
        return self.toHex(self, initVector + cipher.encrypt(stringIn))

    def aes_decrypt(self, stringIn):
        stringIn = codecs.decode(stringIn, "hex_codec")
        initVector = stringIn[:16]
        cipher = AES.new(self.cipherKey.encode(), AES.MODE_CBC, initVector)
        return self.unPad(self, cipher.decrypt(stringIn[16:])).decode()


dataIn  = "Hello World!"
aesHandler = AESHandler("SUPER_SECRET_KEY")

encodedString = aesHandler.aes_encrypt(dataIn)
print("EncodedString:", encodedString)

decodedString = aesHandler.aes_decrypt(encodedString)
print("DecodedString:", decodedString)
0 голосов
/ 01 ноября 2019

Это должно сработать. По сути, я заставил все внутренние устройства работать на bytes, когда это необходимо.

#!pip install pycrypto
import hashlib
import codecs
from Crypto import Random
from Crypto.Cipher import AES


class AESHandler:
    def __init__(self, cipherKey):
        hashedKey = hashlib.sha1(); hashedKey.update(cipherKey.encode())
        self.pad = lambda self, s: s + (self.blockSize - len(s) % self.blockSize) * b'\x00'
        self.unPad = lambda self, s : s.rstrip(b'\x00')
        self.toHex = lambda self, x: b"".join([hex(c)[2:].zfill(2).encode() for c in x])
        self.blockSize = 16
        self.cipherKey = hashedKey.hexdigest()[:32]

    def aes_encrypt(self, stringIn):
        stringIn = self.pad(self, stringIn.encode())
        initVector = Random.new().read(AES.block_size)
        cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
        return self.toHex(self, initVector + cipher.encrypt(stringIn))

    def aes_decrypt(self, stringIn):
        stringIn = codecs.decode(stringIn, "hex_codec")
        initVector = stringIn[:16]
        cipher = AES.new(self.cipherKey, AES.MODE_CBC, initVector)
        return self.unPad(self, cipher.decrypt(stringIn[16:])).decode()


dataIn  = "Hello World! α and ω"
aesHandler = AESHandler("SUPER_SECRET_KEY")

encodedString = aesHandler.aes_encrypt(dataIn)
print("EncodedString:", encodedString)
# EncodedString: b'e8b7621f04310fbb40bb40a22ccc4a62e67fa5124fee5bac858288615028b2519f30516bc84b9a4625c944b4a22f0599'

decodedString = aesHandler.aes_decrypt(encodedString)
print("DecodedString:", decodedString)
# DecodedString: Hello World! α and ω

( EDITED исправить toHex() не работает с bytes)

...