Arti
Arti

Reputation: 7772

Compatible AES encryption between Swift on iOS and Python

On my server I use this code to encrypt data:

class AESCipher(object):

    def __init__(self, key, iv, block_size=32):
        self.bs = block_size
        self.iv = iv
        self.encoder = PKCS7Encoder(block_size=self.bs)
        self.key = hashlib.sha256(key.encode()).digest()

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

And use this code: https://github.com/janglin/crypto-pkcs7-example/blob/master/pkcs7.py for padding.

In my app I use this answer to decrypt and encrypt.

But I get different results: In python:

cipher = AESCipher(BaseConfig.AES_KEY, BaseConfig.AES_IV)
print cipher.encrypt("hello") #returns: Z3FMT0hVaW9RMFFqaHV2SXMOLB2j6ZdRhuUKwE60BBRYa6bgS2gFqgR/VFKXyJiU

In swift:

print(try! "hello".aesEncrypt(GVariables.AESKey, iv: GVariables.AESIv)) //reutrns: 9OpPH19GmTd6n0dsXFJ0mQ==

Upvotes: 1

Views: 1266

Answers (1)

zaph
zaph

Reputation: 112875

The fact that the Python encryption returns 64 Base64 encoded bytes which is 48 data bytes for encrypting 5 bytes indicated that additional information is added to the encrypted data.

Encryption of 5 bytes with AES will result in 16-bytes (one block). So there are an additional 32 bytes in the encrypted data. The answer shows prepending the IV but that is only 16-bytes leaving another 16-bytes unknown.

Note that the code you copied used CFB mode, you probably should use CBC mode.

Best advice given lack of experience with encryption, consider using RNCryptor, there are versions in many languages including RNCryptor-python and RNCryptor iOS and it handles all the details needed for secure encryption.

Upvotes: 3

Related Questions