PKCS#7 signing provides incorrect output
rafa-guillermo opened this issue · comments
I'm trying to connect to an API which requires the endpoint to be signed with PKCS#7 signing. I've got the signing working in python and calling the endpoint results in a correct response.
Using the sample code provided for this with forge however results in a different output than what the py script gives me, and using the result in my request results in an error.
I do notice that when converting the outputs to bytes, the two outputs are very similar, though there are some major differences between the two (the output from forge has a lot of bytes with the value 194 interspersed through it, and in other places bytes with the value 195, with the subsequent byte being +64 of the corresponding byte in the py output.
The code I'm using is just the example code:
var p7 = forge.pkcs7.createSignedData();
p7.content = forge.util.createBuffer('Some content to be signed.', 'utf8');
p7.addCertificate(certOrCertPem);
p7.addSigner({
key: privateKeyAssociatedWithCert,
certificate: certOrCertPem,
digestAlgorithm: forge.pki.oids.sha256,
authenticatedAttributes: [{
type: forge.pki.oids.contentType,
value: forge.pki.oids.data
}, {
type: forge.pki.oids.messageDigest
// value will be auto-populated at signing time
}, {
type: forge.pki.oids.signingTime,
// value can also be auto-populated at signing time
value: new Date()
}]
});
p7.sign();
Example off the byte differences to demonstrate what I mean (bytes in two's compliment, -62 == 194):
JS:
48,-62,-126,5,72,6,9,42,-62,-122,72,-62,-122,-61,-73,13,1,7,2,-62,-96,-62,-126,5,57,48,-62,-126,5,53,2,1,1,49,15,48,13,6,9,96,-62,-122,72,1,101,3,4,2,1,5,0,48,15,6,9,42,-62,-122,72
py:
48,-126,5,68,6,9,42,-122,72,-122,-9,13,1,7,2,-96,-126,5,53,48,-126,5,49,2,1,1,49,15,48,13,6,9,96,-122,72,1,101,3,4,2,1,5,0,48,11,6,9,42,-122,72
All the values of -62 in the forge output are just not there in the py output, removing them and comparing we get:
48,-126,5,68,6,9,42,-122,72,-122,-9,13,1,7,2,-96,-126,5,53,48,-126,5,49,2,1,1,49,15,48,13,6,9,96,-122,72,1,101,3,4,2,1,5,0,48,11,6,9,42,-122,72
48,-126,5,72,6,9,42,-122,72,-122,-9,13,1,7,2,-96,-126,5,57,48,-126,5,53,2,1,1,49,15,48,13,6,9,96,-122,72,1,101,3,4,2,1,5,0,48,15,6,9,42,-122,72
so not identical but close. the other major discrepancy I found is that in the forge byte array there are often byte pairs [-61, x], which seem to correspond to a single byte in the py byte array with a value of x-64
here's an example:
js:
-61,-118,-62,-112,-62,-71,-61,-72,-61,-93
py:
54,-112,-71,-8,-29
step by step so you can see the correspondence:
adding in square brackets just to show the byte pairs that start with -61:
[-61, -118], -62, -112, -62, -71, [-61, -72], [-61, -93]
remove the -62s:
[-61, -118], -112, -71, [-61, -72], [-61, -93]
add 64 to the second half of the byte pairs where the left-hand byte is -61:
[-61, -118 + 64], -112, -71, [-61, -72 + 64], [-61, -93 + 64]
[-61, -54], -112, -71, [-61, -8], [-61, -29]
remove the -61s from the byte pairs and we get the same as the py bytes:
-54, -112, -71, -8, -29