Skip to content

Conversation

@e159669
Copy link

@e159669 e159669 commented Nov 4, 2025

This plugin can take care of generating jws signature creation and/or jws signature verification. To enable jws signing support,
you need to configure in the environment the signatureConfig property.

@karen-avetisyan-mc karen-avetisyan-mc added the safe The PR has been reviewed by Mastercard and has been validated to be safe label Nov 4, 2025
@e159669
Copy link
Author

e159669 commented Nov 11, 2025

Please refer this document for JWS support design document and use case summary
Uploading JWS.Signature.Support.-design.document.docx…

@sonarqubecloud
Copy link

Copy link
Contributor

@joseph-neeraj joseph-neeraj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a design/requirement doc for this.Please send us a link.
The JWS header seems to use custom configuration, with an iat in the header and crit iat. We need some context on this. If this is a one off and not the generic design across APIs in Mastercard, we'll have to re-think if this should be merged to the common/public repo.

const jwsHeaders = jwsParts[0];
const jwsSignature = jwsParts[2];
const jwsSign = jwsHeaders + '.' + jwsPayload + '.' + jwsSignature;
const isVerified = KJUR.jws.JWS.verify(jwsSign, publicKeyPEM, [algo]);
Copy link
Contributor

@joseph-neeraj joseph-neeraj Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this response JWS header have the crit: [ "iat" ] and "iat" keys ? if so is it verified here ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Please refer to this comment , to decide whether this change needs to be implemented or not.

iat in the header is a custom header value as far as I can tell.
Nothing in the code or jsrassign's docs suggest that it will be checked automatically.
the lib only seems to be verifying the signature here.
Please verify iat here.

@joseph-neeraj
Copy link
Contributor

Please refer this document for JWS support design document and use case summary Uploading JWS.Signature.Support.-design.document.docx…

The link directs to this page again, please mail us the valid link.

@e159669

This comment was marked as off-topic.

@joseph-neeraj
Copy link
Contributor

Hello @joseph-neeraj @karen-avetisyan-mc Please refer below links for understanding the design and implementation of this JWS Digital Signature Guide | Account to Account Commerce for Creditor Service Providers | Mastercard D…](https://developer.mastercard.com/account-to-account-commerce-for-csp/documentation/tutorials-and-guides/jws-guide/)

  1. I've removed the internal link.
  2. The JWS signing guide seems to be for a specific platform, we'll need to discuss this internally to see if this should be merged to the public repo. A lot of the implementation details seem to be custom, just specific to the Zapp platform. We'll check this and let you know if we should go ahead with merging the PR to this repo.


function jwsVerify(jws, expectedPayload, publicKeyPEM, algo) {
const stringPayload = JSON.stringify(expectedPayload);
const jwsPayload = Buffer.from(stringPayload, 'binary').toString('base64url');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as my previous comment, please check this again, as per nodejs' documentation 'binary' is an alias for 'latin1', so any unicode character which does not fit into latin1 will be truncated.
the english alphabet will fit but a lot of other characters won't and will result in data loss, resulting in incorrect signature computation. Please use utf-8 when reading the string to the buffer and see if it works.

Suggested change
const jwsPayload = Buffer.from(stringPayload, 'binary').toString('base64url');
const jwsPayload = Buffer.from(stringPayload, 'utf-8').toString('base64url');

const jwsHeaders = jwsParts[0];
const jwsSignature = jwsParts[2];
const jwsSign = jwsHeaders + '.' + jwsPayload + '.' + jwsSignature;
const isVerified = KJUR.jws.JWS.verify(jwsSign, publicKeyPEM, [algo]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Please refer to this comment , to decide whether this change needs to be implemented or not.

iat in the header is a custom header value as far as I can tell.
Nothing in the code or jsrassign's docs suggest that it will be checked automatically.
the lib only seems to be verifying the signature here.
Please verify iat here.

Comment on lines +22 to +26
const requestConfig = utils.getRequestConfig(mcContext.signatureConfig, mcContext.url);

if (!requestConfig) {
return
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these to the line just after
const mcContext = new MastercardContext(context);

None of the payload or signature calculations matter if the request does not have any signature configuration.

const url = new URL(requestUrl);
payload = url.pathname + url.search;
} else {
payload = body.text ? body.text : undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check has already been done by hasBody

Suggested change
payload = body.text ? body.text : undefined;
payload = body.text


function jwsSign(payload, KID, privateKeyPEM, algo) {

const header = { "alg": algo, "kid": KID, "crit": [ "iat" ], "iat": KJUR.jws.IntDate.get("now").toString()};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the implementation guide iat is a number. Please fix this. I suppose it needs to be fixed on the server side as well .

return detachedJWS;
}

function jwsVerify(jws, expectedPayload, publicKeyPEM, algo) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that these suggestions are applicable only if we don't merge the PR to this repo.
These are requirements for the zapp platform and may not be applicable in a generic sense.
So please hold off implementing these until we decide on whether these are going into this repo.

A few checks from the implementation guide are missing here:

  1. Check that crit header only contains iat.
  2. alg should only be RS256.
  3. Verify the iat header value. It should be a number and within tolerance levels to account for network delays/clock skews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe The PR has been reviewed by Mastercard and has been validated to be safe

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants