SecKeyVerifySignature не удалось ecdsaSignatureDigestX962 - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь подписать и проверить проблему с помощью алгоритмов кривой эллипти c, используя инструменты Apple.

Используя SecKeyCreateWithData, я могу использовать / импортировать уже сгенерированные открытые / закрытые ключи, это прекрасно работает , Затем я вызываю функцию sign (), которая принимает параметр SecKeyAlgorithm. В моем случае это ecdsaSignatureDigestX962, потому что я использую кривую secp256r1 (NIST P-256). Таким образом, подпись не удалась, но тогда проверка всегда выполняется sh с:

Can't verify/wrong signature Unmanaged<CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-67808 "EC signature verification failed (ccerr -7)" UserInfo={NSDescription=EC signature verification failed (ccerr -7)})

Вот мой полный код, если у кого-то есть идея:

import UIKit

class SecureEnclave: UIViewController {

    var publicKey: SecKey!
    var privateKey: SecKey!
    var signature: Data!

    override func viewDidLoad() {
        super.viewDidLoad()

        if #available(iOS 10.0, *) {

            var error: Unmanaged<CFError>?

            //Step 1: Private Key
            let privKeyUInt8: [UInt8] = [0x04,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0x**,0xde,0x0a,0x37,0x02,0xfc,0xc6,0x04,0x5b,0x03,0xd7,0x12,0x03,0x26,0x6a,0x4b,0x3d,0x05,0x55,0x5d,0x90,0xe1,0xa4,0xcf,0xd1,0x78,0xf7,0x95,0xda,0xa3,0x9c,0x**,0x2c,0x37,0x4f,0x**,0xfa,0x28,0x2e,0x64,0x7a,0x22,0x7f,0x47,0x9a,0x98,0x1a,0x2c,0x9b,0x2d,0x28,0x96,0xe0,0x**,0x07,0x33,0x06,0x10,0x5a,0x95,0x85,0x9c,0xc3,0xfd,0x43,0xf4,0x81,0x95,0xf4,0xe5,0x6d,0xb2,0x**,0x**,0x**,0x87,0x6d,0xc1,0x52,0x89,0xd3,0x05]

            let CFPrivData = CFDataCreate(nil, privKeyUInt8, privKeyUInt8.count)
            let optionsPrivKey: [String: Any] = [
                                                    kSecAttrKeyType as String         : kSecAttrKeyTypeEC,
                                                    kSecAttrKeyClass as String        : kSecAttrKeyClassPrivate,
                                                ]

            guard let privKey = SecKeyCreateWithData(CFPrivData!, optionsPrivKey as CFDictionary, &error) else {
                 let error = error!.takeRetainedValue() as Error
                 return print(error)
            }

            self.privateKey = privKey

            //Step 2: Public Key
            let pubKeyUInt8: [UInt8] = [0x04,0x09,0x44,0x11,0xc6,0xbe,0x9f,0x31,0x88,0xa0,0x23,0xe7,0xf1,0x77,0x13,0xef,0xde,0x0a,0x37,0x02,0xfc,0xc6,0x04,0x5b,0x03,0xd7,0x12,0x03,0x26,0x6a,0x4b,0x3d,0x05,0x55,0x5d,0x90,0xe1,0xa4,0xcf,0xd1,0x78,0xf7,0x95,0xda,0xa3,0x9c,0x18,0x2c,0x37,0x4f,0x1b,0xfa,0x28,0x2e,0x64,0x7a,0x22,0x7f,0x47,0x9a,0x98,0x1a,0x2c,0x9b,0x2d]

            let CFPubData = CFDataCreate(nil, pubKeyUInt8, pubKeyUInt8.count)

            let optionsPubKey: [String: Any] = [kSecAttrKeyType as String: kSecAttrKeyTypeEC,
                                          kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
                                          kSecAttrKeySizeInBits as String: 256]

            guard let pubKey = SecKeyCreateWithData(CFPubData!, optionsPubKey as CFDictionary, &error) else {
                let error = error!.takeRetainedValue() as Error
                return print(error)
            }

            self.publicKey = pubKey

            //Step 3: Signing/Verifing

            let challengeString = "Hello"
            let challengeData = challengeString.data(using: .utf8)

            self.sign(algorithm: .ecdsaSignatureDigestX962, data: challengeData!)

        } else {
            print("unsupported")
        }

    }

    private func sign(algorithm: SecKeyAlgorithm, data: Data) {

        guard SecKeyIsAlgorithmSupported(self.privateKey!, .sign, algorithm) else {
            print("Algorith not supported - Can't sign")
            return
        }

        // SecKeyCreateSignature call is blocking when the used key
        // is protected by biometry authentication. If that's not the case,
        // dispatching to a background thread isn't necessary.
        DispatchQueue.global().async {
            var error: Unmanaged<CFError>?
            let signature = SecKeyCreateSignature(self.privateKey!, algorithm, data as CFData, &error) as Data?

            DispatchQueue.main.async {
                self.signature = signature

                guard signature != nil else {
                    print((error!.takeRetainedValue() as Error).localizedDescription)
                    return
                }
                print("Signature : OK !")

                //Step 4: Verifing

                let algorithm: SecKeyAlgorithm = .ecdsaSignatureDigestX962
                guard SecKeyIsAlgorithmSupported(self.publicKey, .verify, algorithm) else {
                    print("Algorith not supported - Can't verify")
                    return
                }

                var error: Unmanaged<CFError>?
                guard SecKeyVerifySignature(self.publicKey, algorithm, data as CFData, self.signature as CFData, &error) else {
                    print("Can't verify/wrong signature \(error!)")
                    return
                }
                print("Signature check: OK")
            }
        }
    }
}
...