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

Swift生成的RSA公钥导入Node.js失败,求解决方案

Swift RSA公钥传输至Node.js解析错误解决方案

问题根源

Swift通过SecKeyGeneratePair生成的公钥,默认导出的DER格式可能是PKCS#1标准(仅包含模数和指数),而Node.js的crypto模块默认期望X.509(SPKI)格式的公钥,这是导致ASN.1解析错误的核心原因。


具体解决步骤

1. Swift端导出标准X.509格式PEM公钥

确保导出的是SPKI格式的公钥(X.509标准),而非PKCS#1:

func exportPublicKeyToPEM(_ publicKey: SecKey) -> String? {
    var error: Unmanaged<CFError>?
    guard let derData = SecKeyCopyExternalRepresentation(publicKey, &error) as Data? else {
        print(error?.takeRetainedValue() ?? "导出公钥失败")
        return nil
    }
    // 按PEM标准封装:添加头尾标识+64字节换行
    let base64Str = derData.base64EncodedString(options: .lineLength64Characters)
    return "-----BEGIN PUBLIC KEY-----\n\(base64Str)\n-----END PUBLIC KEY-----"
}

注:iOS 10+系统中SecKeyCopyExternalRepresentation对RSA公钥默认导出SPKI格式,无需额外转换。

2. 传输时避免编码错误

通过JSON发送PEM字符串时,直接使用原始字符串,不要手动转义或修改换行符:

let params = ["publicKey": pemPublicKey]
do {
    let jsonData = try JSONSerialization.data(withJSONObject: params)
    // 发起POST请求(示例用URLSession)
    var request = URLRequest(url: URL(string: "http://your-server/upload-key")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = jsonData
    // 发送请求逻辑...
} catch {
    print(error)
}

3. Node.js端明确指定格式解析

接收请求后,明确指定公钥的格式和类型,避免自动识别出错:

const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();

app.use(bodyParser.json());

app.post('/upload-key', (req, res) => {
    const publicKeyPem = req.body.publicKey;
    try {
        const publicKey = crypto.createPublicKey({
            key: publicKeyPem,
            format: 'pem',
            type: 'spki' // 强制指定SPKI格式
        });
        res.send('公钥解析成功');
    } catch (err) {
        console.error(err);
        res.status(500).send('公钥解析失败');
    }
});

app.listen(3000, () => console.log('服务器运行在3000端口'));

排查工具

如果问题仍存在,用以下方式验证:

  • 在Swift端打印导出的PEM字符串,复制到本地文件,执行openssl rsa -pubin -in key.pem -text,验证公钥是否有效
  • 在Node.js端打印req.body.publicKey,确认和Swift端的原始PEM完全一致,无缺失或转义错误
  • 若直接传输DER格式,Node.js需按如下解析:
    const publicKey = crypto.createPublicKey({
        key: Buffer.from(req.body.publicKeyDer, 'base64'),
        format: 'der',
        type: 'spki'
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:30:40