'SignedCms.CheckSignature with SAP certificate is failing
This is a follow-up of this question.
I am writing an external server which gets called by a SAP-Server. The SAP-Server signs the URL with a certificate before it is transmitted. In a previous step the SAP-Server sent the certificate it will be using to sign the URL to my server. So my server has the certificate the SAP-Server is using for signing.
From the SAP-documentation I know the following.
The unsigned URL looks like this
The values of important QueryString-parameters are concatenated (in the same order they appear in the QueryString) to form the "message".
For the given QueryString-ParametersContRep = K1 DocId = 361A524A3ECB5459E0000800099245EC AccessMode = r AuthId = pawdf054_BCE_26 Expiration = 19981104091537
the generated "message" looks like this:
K1361A524A3ECB5459E0000800099245ECrpawdf054_BCE_2619981104091537
The "message" is used to calculate the hash from which the SecKey is calculated. SAP uses the Digital Signature Standard (DSS) to digitally sign the hash value according to PKCS#. The digital signature is appended to the querystring in a parameter with the name SecKey. The SecKey for the chosen procedure is about 500 bytes long. In the example from the SAP-documentation, the arbitary values 0x83, 0x70, 0x21, 0x42 are chosen for the secKey, for the sake of clarity.
The SecKey is base64 encoded and added to the URL.
0x83, 0x70, 0x21, 0x42 gets to "g3AhQg=="
and the transferred URL looks like this
When my server receives the URL I need to check the signature. I recreate the "message" by concatenating the QueryString-parameters the same way as it was described in point 2. (as it is described in the SAP-documentation)
SAP gives this Summary of Technical Information
Format of digital signature: PKCS#7 "signed data"
Public key procedure: DSS
Key length: 512 - 1024 bits
Public exponent: 2^16 + 1
Public key format: X.509 v3 certificate MD (message digest) algorithm: MD5 or RIPEMD-160
The library for checking signatures can be obtained from SAP AG. Because the standard format PKCS#7 was used for the signature, other products can also be used for decoding.I receive an "The hash value is not correct"-Exception on line
cms.CheckSignature(certificates, true);
private void CheckSignature(string secKey, string message, X509Certificate2 cert) { byte[] signature = Convert.FromBase64String(secKey); ContentInfo ci = new ContentInfo(System.Text.Encoding.ASCII.GetBytes(message)); SignedCms cms = new SignedCms(ci, true); X509Certificate2Collection certificates = new X509Certificate2Collection(cert); cms.Decode(signature); try { cms.CheckSignature(certificates, true); } catch(Exception ex) { log.Error(ex.ToString()); } }
Can anybody help, or knows what I am doing wrong?
Solution 1:[1]
Actually the above function CheckSignature works correct
BUT the second parameter 'message' has to be URL-encoded. Or to be more precise, when concatenating you must use the NOT-URL-DECODED queryString values. [with the same spelling (uppercase/lowercase) SAP uses]
ContRep = AA
DocId = 53730C7E18661EDCB1F816798DAA18B2
AccessMode = r
AuthId = CN=NPL (for concatenating 'CN%3DNPL' is used)
Expiration = 20220511173746
will become the message
AA53730C7E18661EDCB1F816798DAA18B2rCN%3DNPL20220511173746
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Markus1980Wien |