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

Swift中对AES生成的对称密钥本身加密的问题排查

问题描述

我们需要实现一套安全机制:对AES生成的对称密钥本身进行加密。
流程如下:后端发送公钥→本地生成对称密钥→用对称密钥加密业务数据→用后端公钥加密对称密钥→将加密后的业务数据、加密后的对称密钥一并返回给后端。

以下是我的实现代码,但我排查不出问题所在,恳请帮忙分析:

加密对称密钥的代码

guard let publicKeyData = Data(base64Encoded: publicKey) else {
    throw EncryptionError.invalidPublicKey
}

// 将后端公钥数据转换为SecKey
let keyAttributes: [CFString: Any] = [
    kSecAttrKeyType: kSecAttrKeyTypeRSA,
    kSecAttrKeyClass: kSecAttrKeyClassPublic,
    kSecAttrKeySizeInBits: 2048 // 根据实际情况调整密钥长度
]

guard let key = SecKeyCreateWithData(publicKeyData as CFData, keyAttributes as CFDictionary, nil) else {
    throw EncryptionError.invalidPublicKey
}

// 将SymmetricKey转换为Data
var secretKeyData = Data(count: secretKey.bitCount / 8)
_ = secretKeyData.withUnsafeMutableBytes { secretKeyDataBuffer in
        secretKey.withUnsafeBytes { secretKeyBuffer in
            secretKeyDataBuffer.copyBytes(from: secretKeyBuffer)
        }
    }

// 用后端公钥加密对称密钥
var error: Unmanaged<CFError>?
guard let encryptedData = SecKeyCreateEncryptedData(
    key,
    .rsaEncryptionOAEPSHA1AESGCM,
    secretKeyData as CFData,
    &error
) else {
    if let error = error {
        throw error.takeRetainedValue()
    }
    throw EncryptionError.encryptionFailed
}

// 将加密后的对称密钥转为base64字符串返回
return (encryptedData as Data).base64EncodedString()

加密业务消息的补充代码

let iv = AES.GCM.Nonce()

do {
    let sealedBox = try AES.GCM.seal(jsonData, using: secretKey, nonce: iv)
    let encryptedMessage = sealedBox.combined!
    return encryptedMessage.base64EncodedString()
} catch {
    throw error
}

排查关键点

  • 公钥格式不匹配:SecKeyCreateWithData要求公钥是ASN.1 DER编码格式(如X.509或PKCS#8),如果后端传的是带-----BEGIN PUBLIC KEY-----头尾的PEM格式,直接base64解码会失败,必须先移除头尾标识再解码。
  • 对称密钥转换冗余:当前把SymmetricKey转Data的写法可以简化,且避免潜在的内存操作问题,建议替换为:
    let secretKeyData = secretKey.withUnsafeBytes { Data($0) }
    
  • RSA加密算法兼容性:.rsaEncryptionOAEPSHA1AESGCM是带AES-GCM的混合加密算法,必须确保后端使用完全相同的算法解密;另外SHA1已被列为不安全哈希算法,建议替换为SHA256(.rsaEncryptionOAEPSHA256AESGCM),同时确认后端支持该算法。如果后端仅支持普通RSA OAEP(不带AES-GCM),则算法不匹配会导致解密失败。
  • 强制解包风险:加密消息代码中sealedBox.combined!是强制解包,若combined为nil会直接崩溃,建议改为安全的可选值处理:
    guard let encryptedMessage = sealedBox.combined else {
        throw EncryptionError.failedToCombineSealedBox
    }
    
  • Nonce未传递:AES GCM的Nonce(即代码中的iv)是解密必需的参数,当前代码仅生成但未将其与加密消息一同返回给后端,会导致后端无法解密业务数据。需要把Nonce的base64字符串和加密消息、加密后的对称密钥一起返回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 19:13:26