Hello,
I have a block of bytes that I need to verify the signature. The public key is known AND base64 encoded. The signature is known AND base64 encoded as it is retrieved from an accompanying file. I have visibility into the python script that generates the signature and I know that a SHA256 digest is created from the block of bytes. That digest is then passed into the ECDSA encryptor using the same "well-known" private bytes.
But I am receiving the error:
[F_MANAGER] Unable to verify signature Error Domain=NSOSStatusErrorDomain Code=-67808 "EC signature verification failed, no match" UserInfo={numberOfErrorsDeep=0, NSDescription=EC signature verification failed, no match}
whenever I try to verify the signature. I've enclosed the code. Both verify and verifyRaw are failing.
If anyone has any insight as to what I am doing wrong, that'd be great.
I have a block of bytes that I need to verify the signature. The public key is known AND base64 encoded. The signature is known AND base64 encoded as it is retrieved from an accompanying file. I have visibility into the python script that generates the signature and I know that a SHA256 digest is created from the block of bytes. That digest is then passed into the ECDSA encryptor using the same "well-known" private bytes.
But I am receiving the error:
[F_MANAGER] Unable to verify signature Error Domain=NSOSStatusErrorDomain Code=-67808 "EC signature verification failed, no match" UserInfo={numberOfErrorsDeep=0, NSDescription=EC signature verification failed, no match}
whenever I try to verify the signature. I've enclosed the code. Both verify and verifyRaw are failing.
If anyone has any insight as to what I am doing wrong, that'd be great.
Code Block private var algorithm: SecKeyAlgorithm = .ecdsaSignatureDigestX962SHA256 /** Generates a public key using the 256 bit Elliptic Curve Signature (a 256 bit EC public key is 65 bytes long and starts with an 04.) */ func getPublicKey(keyAsBytes: [UInt8]) -> SecKeyPair { let keyType = kSecAttrKeyTypeECSECPrimeRandom let keySize = 256 let privateData = Data(base64Encoded: privateKey) let privateKeyParams: [String: AnyObject] = [kSecAttrIsPermanent as String: false as AnyObject, kSecAttrApplicationTag as String: privateData?.bytes as AnyObject] let publicKeyParams: [String: AnyObject] = [kSecAttrIsPermanent as String: false as AnyObject, kSecAttrCanVerify as String: true as AnyObject, kSecAttrApplicationTag as String: keyAsBytes as AnyObject] let parameters: [String: AnyObject] = [kSecAttrKeyType as String: keyType, kSecAttrKeySizeInBits as String: keySize as AnyObject, kSecPublicKeyAttrs as String: publicKeyParams as AnyObject, kSecPrivateKeyAttrs as String: privateKeyParams as AnyObject] var publicKey, privateKey: SecKey? _ = SecKeyGeneratePair(parameters as CFDictionary, &publicKey, &privateKey) return SecKeyPair(publicKey: publicKey, privateKey: privateKey) } /* https://stackoverflow.com/questions/21022526/ios-verify-digital-signature, states that Android's Signature class automatically creates a digest(SHA-256) whereas iOS does not */ private func verifyRaw(publicKey: SecKey, updatePackage: Data, signature: Data) -> Bool { /// #define CC_SHA256_DIGEST_LENGTH 32 /// Creates an array of unsigned 8 bit integers that contains 32 zeros var digest = [UInt8](repeating: 0, count:Int(CC_SHA256_DIGEST_LENGTH)) /// CC_SHA256 performs digest calculation and places the result in the caller-supplied buffer for digest (md) _ = updatePackage.withUnsafeBytes { CC_SHA256($0.baseAddress, UInt32(updatePackage.count), &digest) } let result = SecKeyRawVerify(publicKey, .PKCS1SHA256, digest, digest.count, signature.bytes, signature.bytes.count) return result == errSecSuccess } private func verify(publicKey: SecKey, updatePackage: Data, signature: CFData, privateKey: SecKey? = nil) -> Bool { var result = false var pbError:Unmanaged<CFError>? var digest = [UInt8](repeating: 0, count:Int(CC_SHA256_DIGEST_LENGTH)) /// CC_SHA256 performs digest calculation and places the result in the caller-supplied buffer for digest (md) _ = updatePackage.withUnsafeBytes { CC_SHA256($0.baseAddress, UInt32(updatePackage.count), &digest) } let digestAsData = Data(bytes: digest, count: digest.count) if SecKeyVerifySignature(publicKey, algorithm, digestAsData as CFData, signature, &pbError) { result = true } else { Log.error(message: "[F_MANAGER] Unable to verify signature \(pbError!.takeRetainedValue() as Error)") } return result }