You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift RSA加密后如何解密?及与Android加密一致性验证

嘿,我帮你分析下问题所在,以及怎么调整代码让iOS和Android的加解密流程对齐~

问题核心:填充方式不匹配

你iOS代码里用的是PKCS1填充,但Android端用的是OAEP-SHA256填充,这两种填充规则完全不同,导致两边加密的结果无法互相解密,这是最主要的问题。

第一步:修改iOS加密代码,对齐Android的填充规则

从iOS 10开始,系统提供了更灵活的加密API,我们可以直接指定和Android一致的RSA-OAEP-SHA256算法,替换原来的PKCS1填充逻辑。修改后的加密函数如下:

static func encrypt(string: String, publicKey: SecKey) -> String? {
    // 把要加密的字符串转成UTF-8数据,和Android的编码一致
    guard let plainData = string.data(using: .utf8) else {
        print("字符串转UTF-8失败")
        return nil
    }
    
    // 指定和Android完全匹配的加密算法:RSA-OAEP-SHA256
    let encryptionAlgorithm = SecKeyAlgorithm.rsaEncryptionOAEPSHA256
    // 先验证公钥是否支持该算法
    guard SecKeyIsAlgorithmSupported(publicKey, .encrypt, encryptionAlgorithm) else {
        print("当前公钥不支持RSA-OAEP-SHA256加密")
        return nil
    }
    
    var encryptionError: Unmanaged<CFError>?
    // 使用新API进行加密,自动处理OAEP填充和SHA256哈希
    guard let encryptedData = SecKeyCreateEncryptedData(
        publicKey,
        encryptionAlgorithm,
        plainData as CFData,
        &encryptionError
    ) as Data? else {
        print("加密失败:\(encryptionError?.takeRetainedValue().localizedDescription ?? "未知错误")")
        return nil
    }
    
    // 转成Base64字符串,和Android的编码格式一致
    return encryptedData.base64EncodedString()
}

另外,你的公钥解析代码基本没问题,但可以去掉kSecReturnPersistentRef : kCFBooleanTrue这个属性——你只是临时创建公钥对象,不需要持久化引用,简化后的attributes可以写成:

var attributes: CFDictionary {
    return [
        kSecAttrKeyType: kSecAttrKeyTypeRSA,
        kSecAttrKeyClass: kSecAttrKeyClassPublic,
        kSecAttrKeySizeInBits: 2048
    ] as CFDictionary
}
第二步:iOS端解密的实现(如果需要)

如果要在iOS端解密Android加密的内容,或者解密自己加密的结果,需要用对应的私钥,并且同样使用OAEP-SHA256算法,代码示例:

static func decrypt(encryptedString: String, privateKey: SecKey) -> String? {
    // 把Base64字符串转成加密数据
    guard let encryptedData = Data(base64Encoded: encryptedString) else {
        print("Base64解码失败")
        return nil
    }
    
    let decryptionAlgorithm = SecKeyAlgorithm.rsaEncryptionOAEPSHA256
    guard SecKeyIsAlgorithmSupported(privateKey, .decrypt, decryptionAlgorithm) else {
        print("当前私钥不支持RSA-OAEP-SHA256解密")
        return nil
    }
    
    var decryptionError: Unmanaged<CFError>?
    guard let decryptedData = SecKeyCreateDecryptedData(
        privateKey,
        decryptionAlgorithm,
        encryptedData as CFData,
        &decryptionError
    ) as Data? else {
        print("解密失败:\(decryptionError?.takeRetainedValue().localizedDescription ?? "未知错误")")
        return nil
    }
    
    // 把解密后的二进制转成UTF-8字符串
    return String(data: decryptedData, encoding: .utf8)
}
第三步:验证加密流程的一致性

现在调整后,两边的加密流程已经对齐了,确认以下几点:

  • 填充规则:iOS用rsaEncryptionOAEPSHA256,对应Android的RSA/NONE/OAEPWITHSHA-256ANDMGF1PADDING,完全匹配
  • 密钥长度:都是2048位,没问题
  • 字符编码:两边都用UTF-8编码原始字符串
  • Base64编码:iOS的base64EncodedString()是标准无换行格式,和Android API>=O的Base64.getEncoder()一致;如果Android低版本用的是Base64.DEFAULT(会带换行),建议让Android改成Base64.NO_WRAP,或者iOS解码时先去掉换行符

另外还要注意:确保iOS使用的公钥和Android从X.509证书中取出的公钥是同一对密钥的公钥,否则也会导致加解密失败。

内容的提问来源于stack exchange,提问作者Shubham1212

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:17:33