Kotlin Multi Platform(KMM)是否支持AES-128加密逻辑跨端实现?
KMM/iOS 兼容AES加密实现方案
你原Android端代码调用Cipher.getInstance("AES")默认使用的是 AES/ECB/NoPadding 加密规则,以下方案完全对齐该逻辑:
方案1:KMM expect/actual 原生分层实现
不需要引入第三方依赖,分别实现双端逻辑:
common层定义
// commonMain 目录下代码 expect object Crypto { fun calculateHash(data: ByteArray, key: ByteArray): ByteArray }
Android端实现
直接复用原有逻辑即可,无需修改:
// androidMain 目录下代码 import javax.crypto.Cipher import javax.crypto.SecretKey import javax.crypto.spec.SecretKeySpec actual object Crypto { actual fun calculateHash(data: ByteArray, key: ByteArray): ByteArray { val cipher: Cipher var encrypted = ByteArray(16) try { val secretKeyEcb: SecretKey = SecretKeySpec(key, "AES") cipher = Cipher.getInstance("AES") cipher.init(Cipher.ENCRYPT_MODE, secretKeyEcb) encrypted = cipher.doFinal(data, 0, 16) } catch (e: Exception) { e.printStackTrace() } return encrypted.copyOf(8) } }
iOS端实现
基于iOS系统原生CommonCrypto库实现:
- 首先在iosMain的编译配置中添加CommonCrypto的cinterop配置,创建
src/iosMain/cinterop/CommonCrypto.def文件,内容为:
headers = CommonCrypto/CommonCrypto.h
- 编写iOS端实现代码:
// iosMain 目录下代码 import platform.CommonCrypto.* import kotlinx.cinterop.* actual object Crypto { actual fun calculateHash(data: ByteArray, key: ByteArray): ByteArray { require(data.size >= 16) { "输入数据长度不能小于16字节" } require(key.size in listOf(16, 24, 32)) { "AES密钥长度需为16/24/32字节" } val encrypted = ByteArray(16) val encryptStatus = key.usePinned { keyPin -> data.usePinned { dataPin -> encrypted.usePinned { outPin -> CCCrypt( op = kCCEncrypt, alg = kCCAlgorithmAES, options = 0u, // 0对应无填充,ECB模式无需传入IV key = keyPin.addressOf(0), keyLength = key.size.toULong(), iv = null, dataIn = dataPin.addressOf(0), dataInLength = 16u, dataOut = outPin.addressOf(0), dataOutAvailable = encrypted.size.toULong(), dataOutMoved = cValue<ULongVar>() ) } } } check(encryptStatus == kCCSuccess) { "加密失败,错误码:$encryptStatus" } return encrypted.copyOf(8) } }
方案2:使用kotlinx-crypto官方跨平台加密库
直接在common层实现一套代码兼容双端,无需分别编写原生逻辑:
- 项目中引入kotlinx-crypto依赖
- common层实现代码:
// commonMain 目录下代码 import kotlinx.crypto.Aes import kotlinx.crypto.Cipher import kotlinx.crypto.mode.ECB import kotlinx.crypto.padding.NoPadding object Crypto { fun calculateHash(data: ByteArray, key: ByteArray): ByteArray { val cipher = Cipher(Aes, ECB, NoPadding) cipher.init(Cipher.ENCRYPT_MODE, Aes.Key(key)) val encryptedResult = cipher.doFinal(data.copyOfRange(0, 16)) return encryptedResult.copyOf(8) } }
注意:ECB加密模式安全性较低,如非兼容旧逻辑的必要,生产环境建议替换为带IV的CBC、GCM等更安全的加密模式。
内容的提问来源于stack exchange,提问作者mittapalli hareesh
相关产品推荐
相关产品推荐

