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

Swift中RSA私钥从数据创建失败问题的解决方法

RSA私钥创建失败(Code=-50)的解决方案

问题背景

使用自定义RSA结构体执行解密操作时,在创建SecKey私钥实例环节报错:

Optional(Swift.Unmanaged<__C.CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "RSA private key creation from data failed" UserInfo={numberOfErrorsDeep=0, NSDescription=RSA private key creation from data failed}))

核心原因

你的私钥是PKCS#8格式的Base64字符串,但SecKeyCreateWithData默认会按PKCS#1格式解析私钥数据,格式不匹配导致创建失败。此外,解密环节还存在加密数据处理错误的问题。

解决方案

1. 修改私钥解析属性,适配PKCS#8格式

在解密方法的attributes字典中,新增kSecAttrKeyDataVersion字段指定私钥格式为PKCS#8:

var attributes: CFDictionary {
    return [kSecAttrKeyType         : kSecAttrKeyTypeRSA,
            kSecAttrKeyClass        : kSecAttrKeyClassPrivate,
            kSecAttrKeySizeInBits   : keySizeInBits,
            kSecAttrKeyDataVersion  : kSecAttrKeyDataVersionPKCS8] as CFDictionary
}

2. 修复加密数据的解码错误

加密结果是Base64编码字符串,不能直接转UTF8字节数组,需要先解码为原始二进制数据再传入解密方法:

// 替换原代码中的let buffer = [UInt8](string.utf8)
guard let encryptedData = Data(base64Encoded: string), !encryptedData.isEmpty else {
    print("Invalid encrypted string")
    return nil
}
let buffer = [UInt8](encryptedData)

3. 修正后完整的解密方法

func decrypt(string: String, privateKey: String?) -> String? {
    guard let privateKey = privateKey else { return nil }
    
    let keyString = privateKey
        .replacingOccurrences(of: "-----BEGIN RSA PRIVATE KEY-----\n", with: "")
        .replacingOccurrences(of: "\n-----END RSA PRIVATE KEY-----", with: "")
        .replacingOccurrences(of: "\r\n", with: "")
    guard let data = Data(base64Encoded: keyString, options: .ignoreUnknownCharacters) else { return nil }
    
    var attributes: CFDictionary {
        return [kSecAttrKeyType         : kSecAttrKeyTypeRSA,
                kSecAttrKeyClass        : kSecAttrKeyClassPrivate,
                kSecAttrKeySizeInBits   : keySizeInBits,
                kSecAttrKeyDataVersion  : kSecAttrKeyDataVersionPKCS8] as CFDictionary
    }
    
    var error: Unmanaged<CFError>? = nil
    guard let secKey = SecKeyCreateWithData(data as CFData, attributes, &error) else {
        print(error.debugDescription)
        return nil
    }
    
    // 修复Base64解码逻辑
    guard let encryptedData = Data(base64Encoded: string), !encryptedData.isEmpty else {
        print("Invalid encrypted string")
        return nil
    }
    let buffer = [UInt8](encryptedData)
       
    let keySize = SecKeyGetBlockSize(secKey)
    var messageDecrypted = [UInt8](repeating: 0, count: keySize)
    var messageDecryptedSize = keySize
   
    var status = SecKeyDecrypt(secKey, SecPadding.PKCS1, buffer, buffer.count, &messageDecrypted, &messageDecryptedSize)
   
    if status != noErr {
       print("Decryption Error!")
       return nil
    }
   
    // 仅提取实际解密的有效数据(去除填充的空字节)
    let resultData = Data(bytes: messageDecrypted, count: messageDecryptedSize)
    let result = String(data: resultData, encoding: .utf8)
    print(result)
    return result
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 13:37:06