Response Validation
Every response from Nopan is digitally signed to guarantee authenticity and integrity.
By validating the signature with Nopan’s public key, you ensure that:
- The response came from Nopan (authenticity).
- It has not been tampered with in transit (integrity).
- It cannot later be repudiated (non-repudiation).
We highly recommend our clients to validate the response signatures.
Step 1: Extract Signature Headers
Every Nopan response includes:
SignatureSignature-InputExample response headers:
Signature: nopan_sig=:SflKxwRJSMe...abc123=:
Signature-Input: nopan_sig=("@status" "content-digest" "content-type" "content-length");keyid="nopan-key-001";created=1766678793
Step 2: Build the Response Signature Base
Just like for requests, you must reconstruct the signature base string.
For responses, the components typically include:
Example reconstructed base:
- Response with body
- Response with no body
"content-digest": sha256=:Base64EncodedHashOfBody==:
"content-type": application/json
"content-length": 123
"@status": 200
"@signature-params": nopan_sig=("content-digest" "content-type" "content-length" "@status");keyid="your-key-id";created=1766678793
"@status": 204
"@signature-params": nopan_sig=("@status");keyid="your-key-id";created=1766678793
For responses without a body, content-digest, content-type, and content-length are omitted.
Step 3: Verify with Nopan’s Public Key
Nopan provides you with its public verification key that could be found here.
You must use this key to verify the Base64-decoded Signature against the signature base.
It is recommended to cache the public verification key and renew it every 24 hrs.
Examples verifying the signature:
- Java
- JavaScript
public boolean verifySignature(String signatureBase, String signatureValue, PublicKey publicKey) throws Exception {
Signature verifier = Signature.getInstance("SHA512withECDSA");
verifier.initVerify(publicKey);
verifier.update(signatureBase.getBytes(StandardCharsets.UTF_8));
byte[] decodedSignature = Base64.getDecoder().decode(signatureValue);
return verifier.verify(decodedSignature);
}
const crypto = require('crypto');
function verifySignature(signatureBase, signatureValue, publicKeyPem) {
const verifier = crypto.createVerify('SHA512');
verifier.update(signatureBase);
verifier.end();
const signature = Buffer.from(signatureValue, 'base64');
return verifier.verify(publicKeyPem, signature);
}
Step 4: Handle Validation Results
If the verification succeeds, you can trust the response.
If it fails, treat the response as invalid and do not process it.
- Reject unsigned or invalidly signed responses.
- Log validation failures with enough detail for debugging.
- Check that your signature base construction matches canonicalization rules.
Error Handling
When validation fails, apply the following best practices:
Never process financial data or trigger business logic on unverified responses.