KS
Killer-Skills

x9-jws — x9-jws setup guide x9-jws setup guide, JWS security implementation, X9.150 payment security, JSON Web Signature tutorial, how to use x9-jws, x9-jws alternative, x9-jws vs JSON Web Token, x9-jws install, secure payment processing with x9-jws

v1.0.0
GitHub

About this Skill

Ideal for Secure Payment Processing Agents requiring implementation of the JWS security layer in X9.150 x9-jws is a security implementation guide for JSON Web Signature (JWS) in X9.150, facilitating secure payment transactions.

Features

Explains JWS concept in the context of payment security
Provides reference implementations in the codebase
Offers code snippets for signing, verification, and protected header construction
Supports certificate discovery and freshness validation
Ensures non-repudiation for secure payment processing

# Core Topics

carlosnetto carlosnetto
[0]
[0]
Updated: 2/27/2026

Quality Score

Top 5%
30
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add carlosnetto/x9.150-py/x9-jws

Agent Capability Analysis

The x9-jws MCP Server by carlosnetto is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for x9-jws setup guide, JWS security implementation, X9.150 payment security.

Ideal Agent Persona

Ideal for Secure Payment Processing Agents requiring implementation of the JWS security layer in X9.150

Core Value

Empowers agents to implement secure payment processing using JSON Web Signatures, providing guidance on signing, verification, and non-repudiation, leveraging X9.150 standards and certificate discovery protocols

Capabilities Granted for x9-jws MCP Server

Implementing JWS security for payment transactions
Generating protected headers for secure data exchange
Verifying signatures and ensuring non-repudiation in payment processing

! Prerequisites & Limits

  • Requires knowledge of X9.150 standards
  • Limited to JSON Web Signature (JWS) security implementation
Project
SKILL.md
7.9 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

X9.150 JWS Security Guide

You are an expert guide for implementing the JWS (JSON Web Signature) security layer of X9.150. You help developers understand signing, verification, protected header construction, certificate discovery, freshness validation, and non-repudiation.

How to Help

When the developer asks about JWS in X9.150:

  1. Explain the concept in the context of payment security
  2. Point to reference implementations in the codebase
  3. Provide code snippets adapted to the developer's language/framework
  4. Warn about common pitfalls specific to X9.150

Always read the reference implementations when giving specific guidance:

  • qr_server.pysign_jws() and verify_jws() functions are the canonical implementation
  • qr_payer.py — payer-side JWS construction and verification

JWS Structure in X9.150

A JWS token is three Base64url-encoded parts separated by dots: Header.Payload.Signature

Protected Header Construction

json
1{ 2 "alg": "ES256", 3 "typ": "payreq+jws", 4 "kid": "<key-id-from-jwks>", 5 "iat": 1706745600, 6 "ttl": 1706745660000, 7 "correlationId": "123e4567-e89b-12d3-a456-426614174000", 8 "crit": ["iat", "ttl", "correlationId"], 9 "x5t#S256": "<base64url-sha256-thumbprint>", 10 "x5c": ["<base64-der-cert>"], 11 "jku": "http://localhost:5001/certs/payee.jwks" 12}

Key Header Fields

FieldRequiredTypeDescription
algYesstringES256 (ECC P-256) or RS256 (RSA) — read dynamically from JWKS alg field
typYesstringpayreq+jws for requests, payresp+jws for responses
kidYesstringKey identifier from JWKS
iatYesint64Issued At — Unix timestamp in seconds
ttlYesint64Time To Live — expiration in Unix milliseconds
correlationIdYesUUIDStandard UUID with dashes for request/response linking
critYesstring[]Must be ["iat", "ttl", "correlationId"]
x5t#S256RecommendedstringBase64url SHA-256 thumbprint of certificate (for cache lookup)
x5cConditionalstring[]Base64-encoded DER certificate chain (used by X9 PKI certs)
jkuConditionalURIJWKS URL (used by self-signed certs from keygen.py)

Algorithm Selection

The algorithm is NOT hardcoded — it's read from the JWKS file:

python
1# From payee.jwks or payer.jwks 2jwk_metadata = jwks["keys"][0] 3alg = jwk_metadata.get("alg", "ES256") # ES256 for ECC, RS256 for RSA

This supports both ECC (P-256) certificates from keygen.py and RSA certificates from X9 Financial PKI.

Certificate Discovery

Verification follows a strict priority order:

Priority 1: x5t#S256 — Thumbprint Cache Lookup

python
1thumbprint = header.get("x5t#S256") 2cache_path = f"payee_db/cache/{thumbprint}.pem" 3if os.path.exists(cache_path): 4 cert = x509.load_pem_x509_certificate(open(cache_path, "rb").read())

Priority 2: x5c — Embedded Certificate Chain

python
1if "x5c" in header: 2 cert_der = base64.b64decode(header["x5c"][0]) # First cert = leaf 3 cert = x509.load_der_x509_certificate(cert_der)

Priority 3: jku — Fetch JWKS from URL

python
1if header.get("jku"): 2 response = requests.get(header["jku"]) 3 jwks = response.json() 4 for key in jwks["keys"]: 5 if key["kid"] == header["kid"] and "x5c" in key: 6 cert_der = base64.b64decode(key["x5c"][0]) 7 cert = x509.load_der_x509_certificate(cert_der)

Thumbprint Calculation

python
1import hashlib, base64 2from cryptography.hazmat.primitives.serialization import Encoding 3 4cert_der = cert.public_bytes(Encoding.DER) 5sha256 = hashlib.sha256(cert_der).digest() 6thumbprint = base64.urlsafe_b64encode(sha256).rstrip(b'=').decode('ascii')

Certificate Caching

After successful verification, cache the certificate by thumbprint:

python
1cache_path = f"cache/{thumbprint}.pem" 2with open(cache_path, "wb") as f: 3 f.write(cert.public_bytes(Encoding.PEM))

Signing a JWS

Reference: qr_server.py:sign_jws()

python
1from jose import jws 2import time, uuid 3 4def sign_jws(payload, private_key_pem, correlation_id=None): 5 iat = int(time.time()) 6 ttl = (iat * 1000) + 60000 # 1 minute TTL 7 8 headers = { 9 "alg": alg, # from JWKS 10 "typ": "payresp+jws", 11 "kid": jwk_metadata["kid"], 12 "iat": iat, 13 "ttl": ttl, 14 "correlationId": correlation_id or str(uuid.uuid4()), 15 "crit": ["correlationId", "iat", "ttl"], 16 "x5t#S256": thumbprint, 17 } 18 # Include x5c for PKI certs, jku for self-signed 19 if x5c: 20 headers["x5c"] = x5c 21 elif jku: 22 headers["jku"] = jku 23 24 return jws.sign(payload, private_key_pem, headers=headers, algorithm=alg)

Verifying a JWS

Reference: qr_server.py:verify_jws() and validate_jws_headers()

Step 1: Extract and Validate Headers

python
1header = jws.get_unverified_header(token)

Step 2: Check Freshness

python
1now = int(time.time()) 2iat = header.get("iat") 3ttl = header.get("ttl") 4 5# iat must not be in the future (60s clock skew) 6if iat > now + 60: 7 raise ValueError("iat is in the future") 8 9# iat must not be too old (8 minute threshold) 10if now - iat > 480: 11 raise ValueError(f"iat is too old ({now - iat}s ago)") 12 13# ttl (milliseconds) must not have expired 14now_ms = int(time.time() * 1000) 15if now_ms > ttl: 16 raise ValueError("JWS has expired (ttl)")

Step 3: Enforce crit (RFC 7515)

python
1crit = header.get("crit", []) 2for field in crit: 3 if field not in header: 4 raise ValueError(f"Critical header '{field}' is missing")

Step 4: Discover Certificate (see priority order above)

Step 5: Verify Signature

python
1payload = jws.verify(token, cert.public_key(), algorithms=['ES256', 'RS256'])

Step 6: Validate correlationId (Non-Repudiation)

python
1# For fetch responses: response correlationId must match request correlationId 2if response_header["correlationId"] != request_correlation_id: 3 raise ValueError("correlationId mismatch — possible replay or MITM")

Common Pitfalls

1. iat vs ttl units

  • iat is in seconds (Unix timestamp)
  • ttl is in milliseconds (Unix timestamp × 1000 + offset)
  • Computing ttl: ttl = (iat * 1000) + 60000 (1 min after iat)

2. x5c encoding

  • x5c uses standard Base64 (NOT urlsafe)
  • x5t#S256 uses Base64url (no padding)
  • These are different encodings for different purposes

3. Content-Type

  • All JWS endpoints must use Content-Type: application/jose
  • The body IS the JWS token string (not JSON-wrapped)

4. correlationId flow

  • Payer generates a correlationId for the fetch request
  • Server MUST echo the same correlationId in the fetch response
  • This proves the response was generated for THIS specific request
  • For notify, either side can generate the correlationId

5. Algorithm hardcoding

  • NEVER hardcode ES256 — always read from JWKS alg field
  • The system supports both ECC (ES256) and RSA (RS256) certificates
  • X9 Financial PKI uses RSA; self-signed test certs use ECC

6. Missing crit enforcement

  • If a field is listed in crit but absent from the header, the JWS MUST be rejected
  • Recipients MUST validate all fields listed in crit
  • This is per RFC 7515 Section 4.1.11

7. Signature corruption detection

  • Use --failSignature flag to test signature verification
  • The server modifies the first character of the signature part
  • Your implementation should catch InvalidSignatureError

Testing JWS Security

Use the built-in test flags to verify your implementation handles failures:

bash
1# Test signature verification 2python qr_server.py --failSignature 3 4# Test freshness (iat 11 min ago — exceeds 8 min threshold) 5python qr_server.py --failiat 6 7# Test TTL expiration 8python qr_server.py --failttl 9 10# Test correlationId non-repudiation 11python qr_server.py --failCorrelationId 12 13# Test missing mandatory headers 14python qr_payer.py --failjwscustom

Related Skills

Looking for an alternative to x9-jws or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication