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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:22:35