tasos-py / AES-Encryption-Classes

AES encryption in Python, PHP, C#, Java, C++, F#, Ruby, Scala, Node.js
MIT License
145 stars 58 forks source link

Objective-C support request #9

Closed shujaat-github closed 1 year ago

shujaat-github commented 2 years ago

AES-Encryption-Classes already supports variety of languages and for that, like me, all the users of this library will definitely be grateful to you.

My humble request is that if you please add Objective-C support in this library then it will not only help me but this library will also become yet more general.

Thank you!

tasos-py commented 2 years ago

I'm afraid I can't help with that, because I don't know Objective-C. I could give you details on data format and algo parameters, if you want to write the code yourself, but other than that I can't help much

shujaat-github commented 2 years ago

I could give you details on data format and algo parameters, if you want to write the code yourself,

That will definitely help.

tasos-py commented 2 years ago

Alright, let me give you the details. There are three main components,
a) encryption - AES with 128, 192 and 256 bit keys, in CBC or CFB8 mode,
b) authentication - HMAC,
c) and key derivation - PBKDF2 for passwords, and HKDF for keys.
Let's see how those parts are combined in more detail, using AesEncryption.class.php for reference.

In encryption, we generate 16 random bytes for salt L65 and 16 for IV L66. Next we use the salt and password to generate a pair of keys for encryption and authentication L68.

If a password is supplied, the key is generated with PBKDF2 L272 with the following parameters,
PBKDF2(password=password, salt=salt, dKeyLength=AESKeyLength+HMACKeyLength, iterations=20000, digest=SHA512).
Else, if a key is set (either with setMasterKey() or with randomKeyGen()), the key is generated with HKDF L277 with parameters,
HKDF(key=key, salt=salt, dKeyLength=AESKeyLength+HMACKeyLength, digest=SHA256).
Then we split the derived key in two parts, the first n bytes for the AES key and the last 32 bytes for the HMAC key L283.

Next we create an AES cipher with the generated AES key, IV, and selected mode L69,
AES(mode=CBC|CFB8, size=keyLength, key=key, iv=iv)
and use it to encrypt the plaintext L71.

Then we use HMAC to sign the IV and ciphertext with the HMAC key we generated above L72,
HMAC(key=key, data=IV+ciphertext, digest=SHA256).

Finally, we join the salt, IV, ciphertext and signature, and return them as a base64 encoded string or raw bytes L73,
data = salt[16] + iv[16] + ciphertext[n] + mac[32].

Decryption is about the same, but in reverse order. First we slice the data to get the salt, iv, ciphertext and mac signature L101. We generate a pair of keys L108, and use the HMAC key to verify the IV and ciphertext L109. Verification must be done before decryption, and if it fails decryption must be aborted. If verification succeeds, we create a cipher with the AES key, IV and mode, and use it to decrypt the ciphertext.

I hope I've clarified the procedure. I'd recommend writing and testing each component separately, than put them all together. If you want any further guidance, just let me know