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

Swift从PEM文件创建SecKey报错-50:问题排查与解决

问题

我通过以下OpenSSL命令生成带DES3加密的RSA密钥对:

openssl genrsa -des3 -out WM_IO_my_rsa_key_pair 2048 

尝试用SecKeyCreateWithData从PEM文件加载私钥创建SecKey时,出现错误:SecKeyCreate init(RSAPublicKey) failed: -50,代码实现如下:

import UIKit
import Security

func createKey(pem: String) -> SecKey? {
    let attributes: [NSObject : NSObject] = [
       kSecAttrKeyType: kSecAttrKeyTypeRSA,
       kSecAttrKeyClass: kSecAttrKeyClassPrivate,
       kSecAttrKeySizeInBits: NSNumber(value: 2048)
    ]

    let privateKey = pem
        .replacingOccurrences(of: "-----BEGIN PRIVATE KEY-----", with: "")
        .replacingOccurrences(of: "-----END PRIVATE KEY-----", with: "")
        .split(separator: "\n").joined()

    guard let privateKeyData = Data(base64Encoded: privateKey, options: .ignoreUnknownCharacters) else {
        return nil
    }

    var error: Unmanaged<CFError>?
    return SecKeyCreateWithData(privateKeyData as CFData, attributes as CFDictionary, &error)
}

let privateKey = """
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCpySPOXAAsi1jN
vxDrNfinFOUZlLk38P8BF2ukJWU7OOAXol6TG8fFrn8O+UVW4jjPTZjLT9G6385N
iervmwopS5CtHS2p0ptLm1ExigZAuS/LTaIkw3yugr4b+5roEwL9nFW0Qfd4o/ds
3lKPtdwtO0rfqTfuZ6CqcQP0sTJcky7nk3mIyz6jZOZE2QLL/oF/oUKsi5Wt5uJp
uluZ+gt087Ftm1oGKR8lZt5bucbD7WZnmlckNyUh7O973mqqDZ6zTwrgNuxIBmtr
afNetsgZv6/We56IWenKayWW1xA9icPhmViJtzPU3Gu8HW/FMovyRZAMFD1Yzf+L
eiSGC5x9AgMBAAECggEAGOrN+HEEDYV9yOQrhXlsPokQfkqXTCBwLCbVw0dBrglQ
yecoXgqLrPVI7Fek13VnxPSsYdoa+4Pw8Ow2sGdefGT8nItVskCYTeZDajPJayJC
Y2HHVAHkgG/rmou4VirEG5gf885ilS/rFe0izLhx0amL+XsKHFDVAW6ImBaRP4iU
82fkZtLlh4DLi6w/oNu3ePZkMeTl4aAkJH8gRy2Mzsyl0DNi5+mH0du12BVSca58
iAXEhufIweTvDqb3lx0CR5+0+dbk/MeIvoklDCkPAlK9IOXr9m0UYjWXNYTADLi8
PmQf8k7pf74ma/2bFuT8LakIA6z3HEwLO7iKm4VVOQKBgQDYVG7AJWJL3DDMCpz3
csP+fKccr72Q3VKCZ5uq0jC/Wp4jfNip/b76Rt3xb8nqzgIDntu+B6Vzz6HPB5d4
j8510lNZrRzIQj0unxOx7pJHIGHhGv2dJ00IqVa5aNL8aCNhxXhgR3vIojyoo8R9
nc4WAQu4ID+xOCsqtvNBm6T1jwKBgQDI67Obqjqt1IDWV5/7dJundWEtfGBdHYBd
iuVxoyqOKAeasaWXuUxJgpzy/ukIAuI5WtzR8nP/US8MIUkRj7eXDi3E2tgpkUwZ
IT9StEdXM8UznpyXfQX9oMmlHC8MZRwLJkldcbGMjsfXsVcAMbe+HBmXs+izsxqe
icsEPPe/MwKBgQDU2O5HPAElJrcUa3TZux/AayF5hih8OmcOS6bMQhcYj658uD/t
se6QDd4dyaHf12X/7fPDW36dHjPUoWGVi9jV8GV2HG/vUc0k6/vS3CsstF3ZwFa8
o4iV9xePQeYl1sjJUCQKhwrx8z6/prKT7gpxeAHx3jkMw3klg/CAIwYBXQKBgFIc
OT+Rlv95S9nM352k7wPFrZwoKz2Ck/YmkFQbiYWlCE6I8RKLcIjOLxQDZvqWKxuj
bYEDY7Jg3ChJ5hGeOTorWjsL8LE0JvRSKQ3EjS8vAhVxaa9jMbKQJjgqx3N6Uraf
w/XDQ/scUsFsQRDcQKoZ07+yj5P4yxUlXOlzfRAPAoGBALri0o6PhjRRPwKzE3gO
ClUJ1KTEhA55GOPs5ZDPxDckYigSC+R8nLLxeueFiFkIDrar85tiO9J4P0j7tovB
Ivu6+QWQso3U3RC2Deb3uWagKHOt9m+DB8LdKsLpY/aPUXzPKKXJ4BWVIYExm418
FUzB7PCpc0Cdjg6A7Ca2cP0U
-----END PRIVATE KEY-----
"""

createKey(pem: privateKey)

解决方案

问题根源

错误码-50表示参数无效,核心问题有两点:

  1. 生成的是DES3加密的PKCS#1格式私钥,但代码中使用的是PKCS#8格式的PEM头(-----BEGIN PRIVATE KEY-----),格式不匹配;且iOS原生SecKeyCreateWithData无法直接读取加密私钥,必须先解密。
  2. SecKeyCreateWithData要求输入的私钥数据为未加密的PKCS#8格式DER编码数据,原始PKCS#1格式不被支持。

修复步骤

1. 转换私钥格式为未加密的PKCS#8

使用OpenSSL命令转换格式,执行时需输入生成密钥时设置的密码:

openssl pkcs8 -topk8 -inform pem -in WM_IO_my_rsa_key_pair -outform pem -nocrypt -out unencrypted_pkcs8_key.pem

2. 调整代码适配格式

修改代码以正确处理PKCS#8格式私钥,并添加错误日志便于排查:

import UIKit
import Security

func createKey(pem: String) -> SecKey? {
    let attributes: [NSObject : NSObject] = [
        kSecAttrKeyType: kSecAttrKeyTypeRSA,
        kSecAttrKeyClass: kSecAttrKeyClassPrivate,
        kSecAttrKeySizeInBits: NSNumber(value: 2048)
    ]

    // 清理PEM中的所有空白字符(换行、空格等)
    let cleanedPem = pem
        .replacingOccurrences(of: "-----BEGIN PRIVATE KEY-----", with: "")
        .replacingOccurrences(of: "-----END PRIVATE KEY-----", with: "")
        .components(separatedBy: .whitespacesAndNewlines)
        .joined()

    guard let privateKeyData = Data(base64Encoded: cleanedPem) else {
        print("私钥Base64解码失败")
        return nil
    }

    var error: Unmanaged<CFError>?
    guard let secKey = SecKeyCreateWithData(privateKeyData as CFData, attributes as CFDictionary, &error) else {
        if let error = error?.takeRetainedValue() {
            print("SecKey创建失败: \(error.localizedDescription),错误码: \(CFErrorGetCode(error))")
        }
        return nil
    }
    return secKey
}

// 替换为转换后的未加密PKCS#8私钥内容
let privateKey = """
-----BEGIN PRIVATE KEY-----
# 此处粘贴unencrypted_pkcs8_key.pem中的内容
-----END PRIVATE KEY-----
"""

if let key = createKey(pem: privateKey) {
    print("SecKey创建成功")
} else {
    print("SecKey创建失败")
}

额外说明

  • 若需保留私钥加密状态,iOS原生Security框架无法直接读取,需借助OpenSSL库或第三方加密库先解密为PKCS#8格式数据,再调用SecKeyCreateWithData。
  • 错误码-50常见于参数不匹配场景,比如密钥格式错误、属性设置冲突、Base64解码失败等,添加错误日志可快速定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:15:32