我正在研究ECDSA算法,从API中获取签名,在常量文件中有一个本地公钥.

下面是我的代码,当我试图运行这个并验证签名,然后我在这个链接中得到错误

let publicKey = try P384.Signing.PublicKey.init(derRepresentation: privateKeyPemBytes)

我从catch块收到"incorrectParameterSize"这个错误.有谁知道这个加密算法并能帮我吗?

func verifySignature(signedData: Data, signature: Data, publicKey: String) -> Bool {
    var result = false
    do {
        if #available(iOS 14.0, *) {
            let decodedData = Data(base64Encoded: publicKey)
            let publicKeyPemBytes = [UInt8](decodedData!)
            let publicKey = try P384.Signing.PublicKey.init(derRepresentation: privateKeyPemBytes)

            let hash = SHA256.hash(data: signedData)
            let signing384 = try P384.Signing.ECDSASignature(derRepresentation: signature)
            if publicKey.isValidSignature(signing384, for: hash) {
                result = true
            }
        } else {
            // Fallback on earlier versions
        }
    } catch {
        print("\(error)")
    }
    return result
}

推荐答案

在讨论中发现,公钥具有X.509/SPKI格式,即ASN.1/DER编码,可用作Base64编码字符串

Swift支持两个ASN.ECDSA签名的1/DER签名格式和P1363签名格式(第here条表示差异).

以下代码显示了使用示例数据对两种签名格式的验证:

import Foundation
import Crypto

// message to be signed
let msg = "The quick brown fox jumps over the lazy dog".data(using: .utf8)!
let hash = SHA256.hash(data: msg)

// public key import
let publicKeyX509DerB64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMpHT+HNKM7zjhx0jZDHyzQlkbLV0xk0H/TFo6gfT23ish58blPNhYrFI51Q/czvkAwCtLZz/6s1n/M8aA9L1Vg=="
let publicKeyX509Der = Data(base64Encoded: publicKeyX509DerB64)
let publicKey = try! P256.Signing.PublicKey.init(derRepresentation: publicKeyX509Der!)

// verifying an ASN.1/DER encoded signature
let signatureDerB64 = "MEYCIQCDMThF51R3S3CfvtVQomSO+kotOMH6HfvVcx04a21QwQIhAP2Patj0N3CVoeB6yiZt/gEVh9qQ7mtyvF4FiWBYtE0a"
let signatureDer = Data(base64Encoded: signatureDerB64)
let signature1 = try! P256.Signing.ECDSASignature(derRepresentation: signatureDer!)
print(publicKey.isValidSignature(signature1, for: hash)) // true

// verifying a P1363 encoded signature
let signatureP1363B64 = "gzE4RedUd0twn77VUKJkjvpKLTjB+h371XMdOGttUMH9j2rY9DdwlaHgesombf4BFYfakO5rcrxeBYlgWLRNGg==" 
let signatureP1363 = Data(base64Encoded: signatureP1363B64)
let signature2 = try! P256.Signing.ECDSASignature(rawRepresentation: signatureP1363!)
print(publicKey.isValidSignature(signature2, for: hash)) // true

Swift相关问答推荐

如何在一个角色隔离类上编写自定义==实现?

如何在SWIFT任务中判断当前任务是否已取消(异步/等待)

为什么枚举上的.allCases.forEach不是循环(继续和中断不起作用)?

如何使泡泡上的箭头直达封闭矩形

表视图插座单元测试失败

如何在设备(或常量)地址空间中创建缓冲区?

如何使用Swift宏和@Observable和@Environment?

RealityKit - 从中心zoom 模型

Swift 数组拆分成重叠的块

如何返回一个通过 SwiftUI 中的另一个协议间接继承 View 协议的 struct ?

当变量首次用于其自己的初始化时,如何清除变量...在初始化之前使用错误?

覆盖一个子元素的 HStack 对齐方式

为什么 Swift Tuples 只能在元素个数小于等于 6 的情况下进行比较?

Swift:连接两个数组而不重复共享后缀/前缀

Swift中的分段错误

更新我的 pod 导致 GoogleDataTransport Umbrella 标头出现错误

无法推断泛型参数的参数

Void 函数中意外的非 Void 返回值 (Swift 2.0)

Objective-C 方法与可选需求方法 Swift 冲突

在情节提要中设置的 UITableViewCell 的恢复 ID 和标识符有什么区别