I'm trying to verify a signature I get in the callback of Payconiq (payment-platform)
The signature is put together based on this logic
A JWS represents these logical values separated by dots(.):
- JOSE Header
- JWS Payload (Not included)
- JWS Signature
The signature will be generated as per following instructions:
jws = base64URLEncode(JOSE Header)..base64URLEncode(alg(base64URLEncode(JOSE Header).base64URLEncode(Request Body)))
The data I have available is:
- Certificates -> https://ext.payconiq.com/certificates actual certificate ->
MIIE1zCCBH2gAwIBAgIQHzgeQOjemgrfp6IwTS5XfzAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIEVDQyBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMB4XDTIxMTEyMzAwMDAwMFoXDTIyMTIyNDIzNTk1OVowKDEmMCQGA1UEAxMdZXMuc2lnbmF0dXJlLmV4dC5wYXljb25pcS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARIpLe02lsuMs6G1lQQRw3Zo4GlBwxi1h7EDD6GC9MxYRkkxOQMrJ1UKD3ni4dXcCZjHyv2GGvWhNICOaCso9Elo4IDHzCCAxswHwYDVR0jBBgwFoAU9oUKOxGG4QR9DqoLLNLuzGR7e64wHQYDVR0OBBYEFHUsvJY0jGLPbsoGZeOmkk09+ADEMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEEeDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29FQ0NEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTBLBgNVHREERDBCgh1lcy5zaWduYXR1cmUuZXh0LnBheWNvbmlxLmNvbYIhd3d3LmVzLnNpZ25hdHVyZS5leHQucGF5Y29uaXEuY29tMIIBewYKKwYBBAHWeQIEAgSCAWsEggFnAWUAdQBGpVXrdfqRIDC1oolp9PN9ESxBdL79SbiFq/L8cP5tRwAAAX1MZuRtAAAEAwBGMEQCIErmMHlQjPe/aNTo08NiFGS2hlKeBU5Ubrl9OG7myLWcAiB4bWXL8HOl2oNVci3Cv0RMnNTyMHIrAm8Lw9QQq/UxTQB1AEHIyrHfIkZKEMahOglCh15OMYsbA+vrS8do8JBilgb2AAABfUxm5DUAAAQDAEYwRAIgNEbgqCHIAjLqhRGBmiHRAqNwX5qI1GSlfAbqVq4V/W0CIHRCmucjmXpbVKzPsOfJ6RBPHWSUJJSjiGLf1QTtvliDAHUAKXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4QAAAF9TGbj/QAABAMARjBEAiAlPQGU1X34G+wtrYEpGFodWifIfxfeOwKx9o3qjVr4LAIgUQenz7z8a0zIC5XATCAwEG3uXnbATrl+ss5cu6YqvPowCgYIKoZIzj0EAwIDSAAwRQIhAN5vKyEhzWAj6Wc6bhr8l9YXIGn4e4dNVSYeHcRoK0AkAiAhhXJkG+SzWyp/bFJeCfXbnWw59mww9GOOkoNizKCG6w==
- body -> body of the callback post call
{
"PaymentId": "8016ab30f89882a72c6827e6",
"TransferAmount": 100,
"TippingAmount": 0,
"TotalAmount": 100,
"Currency": "EUR",
"Amount": 100,
"Description": "betaling Webshop Patisserie Stefan",
"Reference": "5902",
"CreatedAt": "2022-06-28T09: 50: 58.298Z",
"ExpireAt": "2022-06-28T10: 10: 58.298Z",
"Status": "SUCCEEDED",
"Debtor": {
"Name": "Nathan",
"Iban": "***51944"
}
}
- signature which is a header of the callback call
eyJ0eXAiOiJKT1NFK0pTT04iLCJraWQiOiJlcy5zaWduYXR1cmUuZXh0LjIwMjIiLCJhbGciOiJFUzI1NiIsImh0dHBzOi8vcGF5Y29uaXEuY29tL2lhdCI6IjIwMjItMDYtMjhUMDk6NTE6MTQuNzE0MjU0WiIsImh0dHBzOi8vcGF5Y29uaXEuY29tL2p0aSI6ImU0OWIzNmNhM2EzM2I4ODIiLCJodHRwczovL3BheWNvbmlxLmNvbS9wYXRoIjoiaHR0cHM6Ly90ZXN0LnBhdGlzc2VyaWVzdGVmYW4ubmV0L2FwaS93ZWJzaG9wY29udHJvbGxlci9DYWxsYmFja1BheWNvbmlxIiwiaHR0cHM6Ly9wYXljb25pcS5jb20vaXNzIjoiUGF5Y29uaXEiLCJodHRwczovL3BheWNvbmlxLmNvbS9zdWIiOiI2MjVlN2ZmMDFlMjRiNzA0NDI5MWNkYzUiLCJjcml0IjpbImh0dHBzOi8vcGF5Y29uaXEuY29tL2lhdCIsImh0dHBzOi8vcGF5Y29uaXEuY29tL2p0aSIsImh0dHBzOi8vcGF5Y29uaXEuY29tL3BhdGgiLCJodHRwczovL3BheWNvbmlxLmNvbS9pc3MiLCJodHRwczovL3BheWNvbmlxLmNvbS9zdWIiXX0..SIG71tYh8l0rRn7n7Bg3e1goWIloBlSwdkkXhXjIHZlelhNgKM4GJcFbimk-sIpdNl8XEOtKHVx_Tf93P3V-GA
I have tried multiple things including:
- C# signature verification using ECDSA with SHA256 certificate => this example worked but with my verify always returns false
- same with this one it always returns false when trying to verify
var verified = false;
byte[] dataToBeVerifiedByteArray =
Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));
//this gets the string of the certificate mentioned above
byte[] cerBytes = Convert.FromBase64String(jwk.X5cValues.First().Waarde);
X509Certificate2 cer = new(cerBytes);
ECDsa ECDKey = cer.GetECDsaPublicKey();
ECParameters ECDsaPublicParam = ECDKey.ExportParameters(false);
using (var ecdsa = ECDsa.Create())
{
ecdsa.ImportParameters(ECDsaPublicParam);
verified = ecdsa.VerifyData(dataToBeVerifiedByteArray,
Encoding.UTF8.GetBytes(signature), HashAlgorithmName.SHA256);
};
return verified;
Can anyone see what I'm doing wrong I can't find any solution. There is a documentation where they just referr to the IETF regarding the verification of the signature -> https://datatracker.ietf.org/doc/html/rfc7515#section-5.2
Payconiq documentation -> https://developer.payconiq.com/online-payments-dock/#the-callback-signature
EDIT: I have not found a solution but just check the headers and fetch the status fysically instead of verifying the signature