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

Swift中如何解析带X.509证书头的RSA公钥?

解决SwiftyRSA中带X.509头公钥的解析与PEM输出问题

问题原因

SwiftyRSA的PublicKey类在初始化时(无论传入带X.509头还是不带头的密钥数据),会自动剥离X.509密钥头,仅保留原始RSA公钥核心数据。这就是你观察到的现象:带X.509头的原始数据字节数更多,但PublicKey实例的pemString()输出和无头公钥完全一致——头确实被添加了,但在解析过程中被自动剥离。

解决方案

根据你的需求分两种情况处理:

1. 仅需正常解析使用带X.509头的公钥

你的现有代码已经完成了解析:let publicKey509 = try! PublicKey(data: publicKey_with_X509_header)生成的PublicKey实例是完全可用的,后续的加密/验证等操作不受影响,SwiftyRSA自动剥离头的逻辑不影响密钥功能。

2. 需要输出带X.509头的PEM格式公钥

不要依赖PublicKey的pemString()方法,直接将添加过头的DER数据手动转换为PEM格式:

if let password = passwordTextField.text {
    // 生成RSA密钥对
    guard let keyPair = try? SwiftyRSA.generateRSAKeyPair(sizeInBits: 2048),
          let privateKeyPem = try? keyPair.privateKey.pemString(),
          let publicKeyPem = try? keyPair.publicKey.pemString()
    else {
        return
    }
    
    // 给公钥数据添加X.509头
    let publicKeyData = try! keyPair.publicKey.data()
    let publicKey_with_X509_header = try! SwiftyRSA.prependX509KeyHeader(keyData: publicKeyData)
    
    // 手动将带X.509头的DER数据转为标准PEM格式
    let base64Content = publicKey_with_X509_header.base64EncodedString(options: [.lineLength64Characters])
    let x509Pem = """
    -----BEGIN PUBLIC KEY-----
    \(base64Content)
    -----END PUBLIC KEY-----
    """
    
    // 对比输出:两者PEM格式会明显不同
    print(publicKeyPem)
    print(x509Pem)
    
    // 后续加密私钥的代码保持不变
    let salt = String.random(length: 32)
    let aesKey = Array(String((password + salt).prefix(32)).utf8)
    let iv = [UInt8](String(salt.prefix(16)).utf8)
    guard let aes = try? AES(key: aesKey, blockMode: CBC(iv: iv), padding: .pkcs7),
          let inputData = privateKeyPem.data(using: .utf8),
          let encryptedBytes = try? aes.encrypt(inputData.bytes)
    else {
        return
    }
    
    let encryptedData = NSData(bytes: encryptedBytes, length: encryptedBytes.count)
    let base64Encrypted = encryptedData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
    
    // 打印最终结果
    print(x509Pem)
    print(base64Encrypted)
    print(salt)
}

关键说明

  • SwiftyRSA的PublicKey实例仅存储RSA公钥的核心数据,因此无论初始化时传入的是带X.509头还是无头数据,pemString()都会输出无头格式。
  • 手动生成带X.509头的PEM时,要保证base64字符串按64字符换行,符合PEM格式规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:48:15