kSecAttrKeyTypeEC 导致 encryptMessageWithPublicKey() 失败

2023-12-15

我正在尝试使用 ECDSA 密钥获取 sha384。 我正在跟进本文但当然,我将 RSA 更改为 EC。

密钥已成功生成,但是encryptMessageWithPublicKey()不起作用:(

方法中的变量“状态”encryptMessageWithPublicKey()返回-50 ...

这是我的代码:

import UIKit
import Security

private let _singletonInstance = AsymmetricCryptoManager()


private let kAsymmetricCryptoManagerApplicationTag = "com.AsymmetricCrypto.keypair"
private let kAsymmetricCryptoManagerKeyType = kSecAttrKeyTypeEC//kSecAttrKeyTypeEC
private let kAsymmetricCryptoManagerKeySize = 384

// private key parameters
let privateKeyParams: [String: AnyObject] = [
    kSecAttrIsPermanent as String: true as AnyObject,
    kSecAttrApplicationTag as String: "com.AsymmetricCrypto.keypair" as AnyObject
]

// private key parameters
let publicKeyParams: [String: AnyObject] = [
    kSecAttrIsPermanent as String: true as AnyObject,
    kSecAttrApplicationTag as String: "com.AsymmetricCrypto.keypair" as AnyObject
]

enum AsymmetricCryptoException: Error {
    case unknownError
    case duplicateFoundWhileTryingToCreateKey
    case keyNotFound
    case authFailed
    case unableToAddPublicKeyToKeyChain
    case wrongInputDataFormat
    case unableToEncrypt
    case unableToDecrypt
    case unableToSignData
    case unableToVerifySignedData
    case unableToPerformHashOfData
    case unableToGenerateAccessControlWithGivenSecurity
    case outOfMemory
}



class AsymmetricCryptoManager: NSObject {

    /** Shared instance */
    class var sharedInstance: AsymmetricCryptoManager {
        return _singletonInstance
    }


    func createSecureKeyPair(_ completion: ((_ success: Bool, _ error: AsymmetricCryptoException?) -> Void)? = nil) {
        // private key parameters
        let privateKeyParams: [String: AnyObject] = [
            kSecAttrIsPermanent as String: true as AnyObject,
            kSecAttrApplicationTag as String: kAsymmetricCryptoManagerApplicationTag as AnyObject
        ]

        // private key parameters
        let publicKeyParams: [String: AnyObject] = [
            kSecAttrIsPermanent as String: true as AnyObject,
            kSecAttrApplicationTag as String: kAsymmetricCryptoManagerApplicationTag as AnyObject
        ]

        // global parameters for our key generation
        let parameters: [String: AnyObject] = [
            kSecAttrKeyType as String:          kAsymmetricCryptoManagerKeyType,
            kSecAttrKeySizeInBits as String:    kAsymmetricCryptoManagerKeySize as AnyObject,
            kSecPublicKeyAttrs as String:       publicKeyParams as AnyObject,
            kSecPrivateKeyAttrs as String:      privateKeyParams as AnyObject,
            ]

        // asynchronously generate the key pair and call the completion block
        DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { () -> Void in
            var pubKey, privKey: SecKey?
            let status = SecKeyGeneratePair(parameters as CFDictionary, &pubKey, &privKey)

            if status == errSecSuccess {
                DispatchQueue.main.async(execute: { completion?(true, nil) })
            } else {
                var error = AsymmetricCryptoException.unknownError
                switch (status) {
                case errSecDuplicateItem: error = .duplicateFoundWhileTryingToCreateKey
                case errSecItemNotFound: error = .keyNotFound
                case errSecAuthFailed: error = .authFailed
                default: break
                }
                DispatchQueue.main.async(execute: { completion?(false, error) })
            }
        }
    }



    private func getPublicKeyReference() -> SecKey? {
        let parameters = [
            kSecClass as String: kSecClassKey,
            kSecAttrKeyType as String: kSecAttrKeyTypeEC,
            kSecAttrApplicationTag as String: kAsymmetricCryptoManagerApplicationTag,
            kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
            kSecReturnRef as String: true,
            ] as [String : Any]
        var ref: AnyObject?
        let status = SecItemCopyMatching(parameters as CFDictionary, &ref)
        if status == errSecSuccess { return ref as! SecKey? }
        else { return nil }
    }


    func encryptMessageWithPublicKey(_ message: String, completion: @escaping (_ success: Bool, _ data: Data?, _ error: AsymmetricCryptoException?) -> Void) {
        DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { () -> Void in

            if let publicKeyRef = self.getPublicKeyReference() {
                // prepare input input plain text
                guard let messageData = message.data(using: String.Encoding.utf8) else {
                    completion(false, nil, .wrongInputDataFormat)
                    return
                }


                let plainText = (messageData as NSData).bytes.bindMemory(to: UInt8.self, capacity: messageData.count)
                let plainTextLen = messageData.count

                // prepare output data buffer
                var cipherData = Data(count: SecKeyGetBlockSize(publicKeyRef))
                let cipherText = cipherData.withUnsafeMutableBytes({ (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
                    return bytes
                })


                var cipherTextLen = cipherData.count

                let status = SecKeyEncrypt(publicKeyRef, .PKCS1SHA384, plainText, plainTextLen, cipherText, &cipherTextLen)

                // analyze results and call the completion in main thread
                DispatchQueue.main.async(execute: { () -> Void in
                    completion(status == errSecSuccess, cipherData, status == errSecSuccess ? nil : .unableToEncrypt)
                    cipherText.deinitialize()
                })
                return
            } else {


                DispatchQueue.main.async(execute: { completion(false, nil, .keyNotFound) }) }
        }
    }


    func decryptMessageWithPrivateKey(_ encryptedData: Data, completion: @escaping (_ success: Bool, _ result: String?, _ error: AsymmetricCryptoException?) -> Void) {
        DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { () -> Void in

            if let privateKeyRef = self.getPublicKeyReference() {
                // prepare input input plain text
                let encryptedText = (encryptedData as NSData).bytes.bindMemory(to: UInt8.self, capacity: encryptedData.count)
                let encryptedTextLen = encryptedData.count

                // prepare output data buffer
                var plainData = Data(count: 1024)
                let plainText = plainData.withUnsafeMutableBytes({ (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
                    return bytes
                })
                var plainTextLen = plainData.count

                let status = SecKeyDecrypt(privateKeyRef, .PKCS1SHA384, encryptedText, encryptedTextLen, plainText, &plainTextLen)

                // analyze results and call the completion in main thread
                DispatchQueue.main.async(execute: { () -> Void in
                    if status == errSecSuccess {
                        // adjust NSData length
                        plainData.count = plainTextLen
                        // Generate and return result string
                        if let string = NSString(data: plainData as Data, encoding: String.Encoding.utf8.rawValue) as String? {
                            completion(true, string, nil)
                        } else { completion(false, nil, .unableToDecrypt) }
                    } else { completion(false, nil, .unableToDecrypt) }
                    plainText.deinitialize()
                })
                return
            } else { DispatchQueue.main.async(execute: { completion(false, nil, .keyNotFound) }) }
        }
    }


}



class ViewController: UIViewController {

    override func viewDidLoad() {
        AsymmetricCryptoManager.sharedInstance.createSecureKeyPair({ success, err in

            if success {

                AsymmetricCryptoManager.sharedInstance.encryptMessageWithPublicKey("thisShouldWork", completion: { (success, data, error) in
                    print(success)
                })

            }

            })

    }

}

errorStatus-50 表示您的密钥大小太大。如需参考,请查找“errSecKeySizeNotAllowed”here.

根据苹果的文档, kSecAttrKeyTypeECSECPrimeRandom and kSecAttrKeyTypeEC(现已弃用)仅支持 256 的密钥大小,内部和外部安全飞地,因此您需要进行以下更改才能使其正常工作:

kAsymmetricCryptoManagerKeySize = 256

RSA 允许更大的密钥大小,这就是您不会收到错误的原因。据说 256 位 EC 密钥与 3072 位 RSA 密钥一样安全。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kSecAttrKeyTypeEC 导致 encryptMessageWithPublicKey() 失败 的相关文章

  • 应用程序图标未刷新

    我更改了新版本应用程序中的图标图像 并且我在设备中安装了旧版本应用程序 然后我安装了新版本 它在 iOS 5 中运行良好 但在 iOS 6 中 图标没有刷新 它仍然显示旧版本图标 徽标 如果没有安装旧版本应用程序 该设备在 iOS 5 和
  • 如何在 Swift 中使用 substringToIndex? [复制]

    这个问题在这里已经有答案了 我在这一行收到编译器错误 UIDevice currentDevice identifierForVendor UUIDString substringToIndex 8 类型 String Index 不符合协
  • 自动调整大小完成后如何获取帧大小

    我想知道 如何以及何时 viewDidLoad viewWillAppear viewDidAppear 可以获得自动调整大小以适合其父视图的 UIViews 框架大小 从你的问题中不清楚你为什么想要它 但我想这是为了布局你的子视图 幸运的
  • iOS Swift 检测键盘事件

    我能以某种方式检测来自 iOS 键盘的事件吗 我想检测此类事件UIViewController哪个没有UITextField或任何此类物体 我只有四个圆圈UIView我想在按下键盘上的按钮时将它们涂成不同的颜色 您没有任何对象可以从键盘获取
  • 使用 Push Transition 效果更改 RootViewcontroller

    在我的iOS应用程序中 我需要更改应用程序之间窗口的rootviewController 因此 当我动态更改我的rootviewcontroller时 它会在更改之前轻拂视图 但我想要的是在更改rootviewcontroller时提供平滑
  • 如何验证使用 php 上传的文件不包含可执行二进制文件?

    使用简单的 Firefox 插件 黑客可以更改他们想要上传的任何文件的 MIME 类型 绕过文件类型检查器 然后 黑客可以使用 GIMP 等程序将 php 脚本嵌入到图像 音频或任何其他文件的二进制数据中 我该如何检查并防止这种情况发生 您
  • 使用 UIActionSheet 更改视图时工具栏项目消失

    当从 a 启动视图时UIActionSheet按钮 通过导航栏后退按钮返回视图后 工具栏虽然仍然可见 但上面没有任何以前的按钮 自从更新到 iOS 6 以来 这个错误就出现了 并且是在模拟器和仅运行 iOS 6 的设备上测试时发生的 如果我
  • iOS App布局错误,调用状态栏

    在主动通话和应用程序布局期间面临状态栏问题 我正在使用自动布局 当我运行应用程序 然后开始通话时 一切正常 UI 会随着状态栏的更改而正确缩放 但是 如果我首先开始通话 然后运行应用程序 应用程序屏幕会移动到底部 20pt 就像它们对新状态
  • 对 UIImage 进行方形裁剪,导致图像拉伸

    当尝试执行 UIImage 的中心裁剪时 我得到以下结果 左侧是原始图像640 1136 右边是适合正方形的裁剪图像UIImageView at 320 320 turns to 我对比率元素进行了相当多的修改 以便它可以正确检测要修剪的量
  • 尝试从独立的 Apple Watch 应用发出网络请求

    当应用程序是独立应用程序时 Apple Watch 是否无法进行网络通话 即使手表已连接到 iPhone 我正在使用新的独立应用程序目标 它没有附带可以发出 WatchConnectivity 请求的配对 iOS 应用程序 我十有八九收到
  • WebGL iOS 渲染为浮点纹理

    我正在尝试在 iOS Safari 上的 WebGL 中渲染浮点纹理 而不是在本机应用程序中 我已经设法让 iOS 读取手动 例如从 JavaScript 创建的浮点纹理 但是当我创建浮点类型的帧缓冲区并使用 GPU 渲染到其中时 它不起作
  • 在 Interface Builder 中的资产目录上使用图像

    是否可以直接在界面生成器上使用添加到资产目录中的图像 这是怎么做到的 在 UIImageView 属性上 我看不到任何引用资产目录上任何图像的选项 Import the images into the xcassets folder 单击右
  • UIBezierPath 的起始和结束角度?

    我在 iOS 中使用如下代码编写了半圆UI贝塞尔路径 and CAShape层 clockWiseLayer CAShapeLayer alloc init CGFloat startAngle M PI 2 CGFloat endAngl
  • ASP.NET MVC 防伪造令牌不安全

    在没有 ssl 的情况下向服务器发出请求时 我实际上可以看到 MVC3 框架以纯文本形式生成的验证令牌密钥 该密钥存储在名为 RequestVerificationToken Lw 的 cookie 中 在混合安全环境中 实际上可以在向非
  • 如何使用自签名证书为 TLS 创建 iOS NWConnection?

    我正在尝试将 Apple 的新 NWConnection 类用于我的 MQTT 客户端 为了进行测试 我需要能够创建到本地测试代理的 TLS 连接 该代理具有自签名证书 到目前为止 我只是使用以下命令设置连接 self connection
  • 海报风格的电子邮件验证

    我正在考虑创建一个类似于Posterous的服务 用户可以在其中发布到固定地址 例如 电子邮件受保护 cdn cgi l email protection然后帖子的身份验证将基于发件人地址和标头签名的某种组合 Posterous 似乎正在做
  • 在模拟器中运行应用程序时删除本地通知的 iOS 权限警报

    我正在尝试编写验收测试KIF https github com kif framework KIF在一个很早就要求本地通知权限的应用程序上 不幸的是 由于 iOS 模拟器安全原因无法使用 KIF 自动接受 iOS 权限警报 https gi
  • 打印附加结构(swift 4)

    我有三个 textifled 用于将数据附加到结构中 如何打印我附加的内容 现在我收到一条错误消息 import UIKit class ViewController UIViewController IBOutlet var c UITe
  • 如何在ios中以编程方式添加水平间距和垂直间距?

    我在 ios 8 中创建了一个应用程序 因为我有 4 个可垂直使用的标签 它应该在某些条件下更改位置 所以我已禁用自动布局并以编程方式设置约束 现在的问题是 我可以设置水平和垂直位置 宽度和高度的约束 但我找不到任何方法来添加标签之间的水平
  • 应用未能及时恢复

    我在一个非常具体的场景中遇到 未能及时恢复 崩溃 我认为与看门狗相关 仅在从后台恢复时 并且仅在进入后台后在很短的时间内执行此操作 a最多几秒钟 这似乎是相关的崩溃日志 Incident Identifier E30F2238 5B15 4

随机推荐