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
相关产品推荐
相关产品推荐

