Cross Platform Aes Encryption Between iOS and Kotlin/Java Using Apples Cryptokit

Cross platform AES Encryption between iOS and Kotlin/Java using Apples CryptoKit

could you try this (or something like it) with your setup. From what I undestand
you need to prefix data with nonce, because data from kotlin/java contains the cipher text plus the tag at the end. CryptoKit needs nonce || ciphertext || tag.

func decrypt(data: Data) -> String {
// need to prefix data with nonce, because data from kotlin/java contains the cipher text plus the tag at the end.
// we want nonce || ciphertext || tag for CryptoKit to be happy
let combine = nonce + data
if let myNewSealedBox = try? AES.GCM.SealedBox(combined: combine),
let res = try? AES.GCM.open(myNewSealedBox, using: mykey),
let myText = try? String(decoding: res, as: UTF8.self) {
return myText
}
return ""
}

How to get compatible encryption version in flutter as in iOS

I finally resolved it myself. Posting the answer over here hoping it helps someone.

I had to change the below line,

from

final key = Key.fromBase64("Some_Key");

to

final key = Key.fromUtf8("Some_Key");

That't it. It works!!

iOS CryptoSwift AES Encryption to Python Decryption works - but not the inverse

In the encrypt() method the IV is not considered. As in aesEncrypt(), the IV must be passed and used when creating the AES object.

Furthermore there are bugs in the encoding: The plaintext must be UTF8 encoded and the ciphertext must be hex encoded:

from Crypto.Cipher import AES
import binascii

def encrypt(key, iv, plaintext):
cipher = AES.new(key, MODE, iv, segment_size=128)
plaintext_bytes = plaintext.encode("utf-8")
ciphertext = cipher.encrypt(plaintext_bytes)
ciphertext_hex = binascii.b2a_hex(ciphertext)
return ciphertext_hex

This function is the counterpart to decrypt(), i.e. encrypt() can be used to generate a ciphertext which can be decrypted with decrypt() (or aesDecrypt()).


In the iOS code there are two bugs, both concerning the encoding: The ciphertext must not be UTF8 encoded, but hex decoded. And the decrypted data must not be hex encoded, but UTF-8 decoded.

A possible fix is:

func aesDecrypt(stringToDecrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = Array<UInt8>(hex: stringToDecrypt)
let decrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).decrypt(data)
return String(bytes: decrypted, encoding: .utf8)!
}

This function is the counterpart to aesEncrypt(), i.e. aesDecrypt() can be used to decrypt a ciphertext generated with aesEncrypt() (or encrypt()).


Regarding security: A static IV is insecure. Instead, the IV should be randomly generated for each encryption. Since the (non-secret IV) is needed for decryption, it is passed along with the ciphertext (typically concatenated).



Related Topics



Leave a reply



Submit