Home > database >  Python Crypto AES 128 with PKCS7Padding different outputs from Swift vs Python
Python Crypto AES 128 with PKCS7Padding different outputs from Swift vs Python

Time:08-06

The output produced by crypto with following key

key = base64.b64decode('PyxZO31GlgKvWm 3GLySzAAAAAAAAAAAAAAAAAAAAAA=') (16 bytes)

and the message = "y_device=y_C9DB602E-0EB7-4FF4-831E-8DA8CEE0BBF5"

My IV object looks like this: iv = base64.b64decode('AAAAAAAAAAAAAAAAAAAAAA==')

Objective C CCCrypt produces the following hash 4Mmg/BPgc2jDrGL XRA3S1d8vm02LqTaibMewJ 9LLuE3mV92HjMvVs/OneUCLD4

It appears to be using AlgorithmAES128 uses PKCS7Padding with the key provided above.

I'm trying to implement the same crypto encode functionality to get an output like 4Mmg/BPgc2jDrGL XRA3S1d8vm02LqTaibMewJ 9LLuE3mV92HjMvVs/OneUCLD4

This is what I've been able to put so far

from Crypto.Util.Padding import pad, unpad
from Crypto . Cipher import AES
class MyCrypt():
    def __init__(self, key, iv):
        self.key = key
        self.iv = iv
        self.mode = AES.MODE_CBC
   
    def encrypt(self, text):
      cryptor = AES.new(self.key, self.mode, self.iv)
      length = 16
      text = pad(text, 16)
      self.ciphertext = cryptor.encrypt(text)
      return self.ciphertext


key = base64.b64decode('PyxZO31GlgKvWm 3GLySzAAAAAAAAAAAAAAAAAAAAAA=')
IV = base64.b64decode('AAAAAAAAAAAAAAAAAAAAAA==')
plainText = 'y_device=y_C9DB602E-0EB7-4FF4-831E-8DA8CEE0BBF5'.encode('utf-8')
crypto = MyCrypt(key, IV)
encrypt_data = crypto.encrypt(plainText)
encoder = base64.b64encode(encrypt_data)
print(encrypt_data, encoder)

This produces the following output Pi3yzpoVhax0Cul1VkYoyYCivZrEliTDBpDbqZ3dD1bwTUycstAF MLSTIjSMiQj instead of 4Mmg/BPgc2jDrGL XRA3S1d8vm02LqTaibMewJ 9LLuE3mV92HjMvVs/OneUCLD4 `

Which isn't my desired output. should I not be using MODE_ECB, or am I using key as intended ?

To add more context

I'm naive to Crypto/ Objective C.

I'm currently pentesting an app, which does some hashing behind the scenes.

Using frida I'm tracing these function calls, and I see the following get populated for swift Objc calls.

CCCrypt(operation: 0x0, CCAlgorithm: 0x0, CCOptions: 0x1, keyBytes: 0x1051f8639, keyLength: 0x10, ivBuffer: 0x1051f8649, inBuffer: 0x2814bd890, inLength: 0x58, outBuffer: 0x16f1c5d90, outLength: 0x60, outCountPtr: 0x16f1c5e10)

Where

CCCrypt(operation: 0x0, CCAlgorithm: 0x0, CCOptions: 0x1, keyBytes: 0x1051f8639, keyLength: 0x10, ivBuffer: 0x1051f8649, inBuffer: 0x280e41530, inLength: 0x2f, outBuffer: 0x16f1c56c0, outLength: 0x30, outCountPtr: 0x16f1c5710)
In buffer:
            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
280e41530  79 5f 64 65 76 69 63 65 3d 79 5f 43 39 44 42 36  y_device=y_C9DB6
280e41540  30 32 45 2d 30 45 42 37 2d 34 46 46 34 2d 38 33  02E-0EB7-4FF4-83
280e41550  31 45 2d 38 44 41 38 43 45 45 30 42 42 46 35     1E-8DA8CEE0BBF5
Key:  16 47
            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
1051f8639  3f 2c 59 3b 7d 46 96 02 af 5a 6f b7 18 bc 92 cc  ?,Y;}F...Zo.....
IV:  16
            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
1051f8649  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

I use https://opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/CommonCrypto/CommonCryptor.h to reference the type of encryption happening based on pointers i.e for Options argument the following is passed 0x1

CodePudding user response:

key = base64.b64decode('PyxZO31GlgKvWm 3GLySzAAAAAAAAAAAAAAAAAAAAAA=') (16 bytes)

Nope, that's 32 bytes. It's true that only 16 are non-zero, making a really poor key, but if you pass 256 bits, you are doing AES-256, and you'll get a different result than you would from AES-128 using the first 128 bits of that key.

Your title mentions PKCS #7 padding, but it looks like your code is padding with zeros. That will change the results as well.

ECB doesn't use an IV. If you can see that the Swift code is using the IV, you might be able to see what mode it's using too, or you could try CBC as a first guess. ECB is insecure in most cases. Of course, using a fixed IV is also insecure.

Your output is longer than it should be (64 bytes instead of 48). Your attempt to do the padding yourself is probably responsible for this.

From <CommonCryptor.h>, we can decode the parameters used in Swift's call to CCCrypt:

Type Value Name Comment
CCOperation 0x0 kCCEncrypt Symmetric encryption.
CCAlgorithm 0x0 kCCAlgorithmAES128 Advanced Encryption Standard, 128-bit block
CCOptions 0x1 kCCOptionPKCS7Padding Perform PKCS7 padding.
CCOptions 0x2 kCCOptionECBMode Electronic Code Book Mode. Default is CBC.

CCOptions is a bit field, and kCCOptionECBMode is not set, so the default is used.

So this is AES-128 in CBC mode with PKCS #7 padding.

  • Related