使用Apples CryptoKit在iOS和Kotlin / Java之间进行跨平台AES加密

时间:2020-04-20 21:07:29

标签: swift kotlin encryption aes apple-cryptokit

我想使用Apples CryptoKit从运行Kotlin应用程序的服务器向iOS应用程序发送加密数据。 我在初始化absolute(val1 - val2) < 10^(-9)和解密数据时遇到问题。一般来说,我不明白Sealboxs AES.GCM.SealedBox的用途。

科特林第一面:

tag

iOS:

        fun ByteArray.aesEncrypt(key: ByteArray, iv: ByteArray? = null): ByteArray {
            return aes(this, Cipher.ENCRYPT_MODE, key, iv)
        }
        private fun aes(self: ByteArray, mode: Int, key: ByteArray, iv: ByteArray?): ByteArray{
            val skey = SecretKeySpec(key, "AES")
            val cipher = Cipher.getInstance("AES/GCM/PKCS5Padding")
            println("MODE: ${cipher.algorithm}")
            iv?.let {
                cipher.init(mode, skey, GCMParameterSpec(128, iv))
            }?: run{
                cipher.init(mode, skey)
            }
            val cipherText = ByteArray(cipher.getOutputSize(self.size))
            var ctLength = cipher.update(self, 0, self.size, cipherText, 0)
            ctLength += cipher.doFinal(cipherText, ctLength)
            return cipherText
        }

当然,双方具有相同的密钥和iv / nonce。我遇到的错误消息是:

    static private let privateKey = SymmetricKey(size: SymmetricKeySize.bits128)
    static private let nonce = AES.GCM.Nonce()

    static func decrypt(_ data: Data) -> Data {
        print("Encrypted data \(data.bytes)")
        print("Private key: \(privateKey.data.bytes)")
        print("Nonce: \(Array(nonce))")
        let boxToDecrypt = try! AES.GCM.SealedBox(combined: data)
        let plainData = try! AES.GCM.open(boxToDecrypt, using: privateKey)
        return plainData
    }

所在行:

CryptoKit.CryptoKitError.incorrectParameterSize

编辑我: 其他有效负载信息:

服务器(科特琳):

let boxToDecrypt = try! AES.GCM.SealedBox(combined: data)

客户端(iOS):

Not encrypted: 0,0,0,0,0,0,0,1
Key: 169,152,60,154,77,50,10,63,60,166,48,129,1,68,219,250
IV: 134,191,34,26,111,146,17,54,31,212,74,14
Encrypted: 158,154,213,95,227,42,155,199,169,183,166,67,139,154,198,172,229,82,34,30,40,188,41,73


1 个答案:

答案 0 :(得分:2)

您可以在设置中尝试这种方法(或类似方法)吗?从我所不理解的 您需要在数据前加上随机数,因为kotlin / java中的数据包含密文和末尾的标记。 CryptoKit需要随机数||密文||标签。

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 ""
}