On iOS I am generating a pair of private and public key with the following code:
extension Data {
var hexString: String {
return map { String(format: "%02hhx", $0) }.joined()
}
}
let privateKey = P256.Signing.PrivateKey()
let publicKey = privateKey.publicKey
print("private key: " + privateKey.rawRepresentation.hexString)
print("public key: " + "04" + publicKey.rawRepresentation.hexString)
let message = "A message to sign"
let signature = try! privateKey.signature(for: message.data(using: .utf8)!)
print("DER signature: " + signature.derRepresentation.hexString)
print("base64 DER signature: " + signature.derRepresentation.base64EncodedString())
From the code I got:
private key: b02f6fd1c1a9986f0e8cc84cd84a5061e46582e9620981d6dadbc0d503c2be4f
public key: 043fbd15edf44c644e2cdaba55db35170521e5c4bd09156b4930cc5721d64be694191e32f33b7a0b583ca301bd76fb2f93df774eddac72add74ef938d236ad1673
DER signature: 304502200ded05de61c062e9b8c5a3af9b18cdb05bd8d19597494869c150d00f490a3a30022100cf1ca3c6a9c8c1f5fb32e8d101179f64c49f9d69d3043dcd2371fff9a5dd74b3
base64 DER signature: MEUCIA3tBd5hwGLpuMWjr5sYzbBb2NGVl0lIacFQ0A9JCjowAiEAzxyjxqnIwfX7MujRARefZMSfnWnTBD3NI3H/+aXddLM=
I tried to verify the DER signature with the keys through the tool here, which the site determined that the signature is valid.
However, if I try to verify the same result with the following Ruby code using OpenSSL:
group = OpenSSL::PKey::EC::Group.new('prime256v1')
key = OpenSSL::PKey::EC.new(group)
public_key_hex = '043fbd15edf44c644e2cdaba55db35170521e5c4bd09156b4930cc5721d64be694191e32f33b7a0b583ca301bd76fb2f93df774eddac72add74ef938d236ad1673'
public_key_bn = OpenSSL::BN.new(public_key_hex, 16)
public_key = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
key.public_key = public_key
data = 'A message to sign'
signature_base64 = 'MEUCIA3tBd5hwGLpuMWjr5sYzbBb2NGVl0lIacFQ0A9JCjowAiEAzxyjxqnIwfX7MujRARefZMSfnWnTBD3NI3H/+aXddLM='
signature = Base64.decode64(signature_base64)
key.dsa_verify_asn1(data, signature)
The signature is determined to be invalid:
irb(main):074:0> key.dsa_verify_asn1(data, signature)
=> false
I am thinking it is probably due to some format issues of the signature but I don't have any idea or direction to look for. Is this the case? Or did I miss something else?