3

I am working on the ECDSA Algorithm where i am taking signature from the APIs and i have one local public key inside constant file.

Below is my code when i am trying to run this and verify the signature then i am getting error in this link

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

I am receiving "incorrectParameterSize" this error from the catch block. Can anyone having idea about this Encryption algorithm and help me out?

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
}
Topaco
  • 40,594
  • 4
  • 35
  • 62
Mayank Patel
  • 3,868
  • 10
  • 36
  • 59
  • Is `privateKeyPemBytes` really DER encoded? A PEM encoded key is converted to a DER encoded key by removing header, footer and line breaks and Base64 decoding the rest (btw there is also `pemRepresentation` for a PEM encoded key). – Topaco Jul 29 '22 at 06:35
  • @Topaco No might be it is not DER Encoded. Can you tell me how to convert privateKeyPemBytes to DER Encode? – Mayank Patel Jul 29 '22 at 06:58
  • The name `privateKeyPemBytes` is misleading, it seems to be a *public* key needed for a verification process (you should change the name). To comprehend the issue, post an example for `publicKey` (or - since it's a public key - `publicKey` itself). – Topaco Jul 29 '22 at 07:15
  • Yes sorry for misleading this type. I just wanted to know how can i fix this? @Topaco I edited my question. – Mayank Patel Jul 29 '22 at 08:16
  • Who should be able to answer without guessing whether `publicKey` was correctly converted to `publicKeyPemBytes` without knowing `publicKey`? Keep in mind that there are different formats and encodings. So please, specify format and encoding, or post an example for `publicKey` (you can also post the real key, since it is a *public* key). – Topaco Jul 29 '22 at 08:28
  • After your most recent edit there is a `publicKeyPemBytes` / `privateKeyPemBytes` mess in your post, which unfortunately is more confusing than helpful. – Topaco Jul 29 '22 at 08:30
  • @Topaco so you need public key? – Mayank Patel Jul 29 '22 at 08:36
  • Yes, unless you can specify the exact format and encoding of the key. – Topaco Jul 29 '22 at 11:08

1 Answers1

1

In the discussion it turned out that the public key has the X.509/SPKI format, is ASN.1/DER encoded and is available as Base64 encoded string.
However, it is a P-256 key and not a P-384 key, which is the cause of the error. The fix is to use P256 in the code instead of P384.
The signature is in ASN.1/DER format, as Base64 encoded string.

Swift supports both the ASN.1/DER signature format and the P1363 signature format for ECDSA signatures (s. here for the difference).

The following code shows the verification for both signature formats using sample data:

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
Topaco
  • 40,594
  • 4
  • 35
  • 62