如何在Swift中用模数和指数生成AWS认证所需的RSA公钥?
Swift 实现 AWS 认证 RSA 公钥生成
对应你提供的 Kotlin 代码,Swift 可以通过 Security 框架实现相同逻辑,核心是处理 URL 安全 Base64 解码、构建 RSA 公钥的 ASN.1 结构,最终生成符合要求的 RSA 公钥。
完整实现代码
import Security func getPublicKey(n: String, e: String) throws -> SecKey { // 处理 URL 安全 Base64 解码 func decodeBase64URL(_ string: String) throws -> Data { var base64 = string .replacingOccurrences(of: "-", with: "+") .replacingOccurrences(of: "_", with: "/") // 补全 Base64 所需的 = 填充符 let padding = base64.count % 4 if padding > 0 { base64.append(String(repeating: "=", count: 4 - padding)) } guard let data = Data(base64Encoded: base64) else { throw NSError(domain: "PublicKeyError", code: 0, userInfo: [NSLocalizedDescriptionKey: "无效的 Base64URL 字符串"]) } return data } let nData = try decodeBase64URL(n) let eData = try decodeBase64URL(e) // 构建 RSA 公钥的 ASN.1 DER 结构 func buildASN1Sequence(with integers: [Data]) throws -> Data { var sequenceData = Data() // 编码每个 Integer 的 ASN.1 格式:Tag(0x02) + Length + Value for intData in integers { // 移除前导零,避免解析错误 var trimmedData = intData while trimmedData.first == 0x00 { trimmedData.removeFirst() } // 若最高位为 1,补 0x00 防止被识别为负数 if let firstByte = trimmedData.first, firstByte & 0x80 != 0 { trimmedData.insert(0x00, at: 0) } // 编码长度字段 let length = trimmedData.count var lengthData = Data() if length < 128 { lengthData.append(UInt8(length)) } else { lengthData.append(0x81) lengthData.append(UInt8(length)) } // 拼接标签、长度、值 sequenceData.append(0x02) sequenceData.append(lengthData) sequenceData.append(trimmedData) } // 编码外层 Sequence:Tag(0x30) + Length + 内部数据 let sequenceLength = sequenceData.count var sequenceHeader = Data() sequenceHeader.append(0x30) if sequenceLength < 128 { sequenceHeader.append(UInt8(sequenceLength)) } else { sequenceHeader.append(0x81) sequenceHeader.append(UInt8(sequenceLength)) } return sequenceHeader + sequenceData } let derData = try buildASN1Sequence(with: [nData, eData]) // 创建 RSA 公钥 let attributes: [CFString: Any] = [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeyClass: kSecAttrKeyClassPublic, kSecAttrKeySizeInBits: nData.count * 8 ] var error: Unmanaged<CFError>? guard let publicKey = SecKeyCreateWithData(derData as CFData, attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } return publicKey }
关键逻辑说明
- URL 安全 Base64 解码:AWS 返回的
n和e采用 URL 安全的 Base64 编码,需替换特殊字符并补全填充符,才能用标准 Base64 解码。 - ASN.1 DER 结构:Security 框架要求公钥必须是 DER 编码的 ASN.1 格式,RSA 公钥的结构是包含模数
n、指数e两个整数的序列。 - SecKey 生成:通过
SecKeyCreateWithData传入 DER 数据和密钥属性,生成可直接用于 AWS 认证的 RSA 公钥。
内容的提问来源于stack exchange,提问作者iParesh
相关产品推荐
相关产品推荐

