DEV Community

Cover image for Module 1 — Identity Authentication and Verification (Capture, Container, Signature, and Initial Personalization Flow)
Antonio Jose Socorro Marin
Antonio Jose Socorro Marin

Posted on

Module 1 — Identity Authentication and Verification (Capture, Container, Signature, and Initial Personalization Flow)

Executive Summary

This first module defines the enrollment flow and the structure of the intelligent container that stores demographic and biometric data (fingerprints, face, iris), protects them cryptographically, and produces verifiable artifacts that can: (a) be stored on a smart card; (b) be signed with keys managed by HSM/PKCS#11; and (c) serve as the basis for securely exportable derived identities. The cryptographic and structural decisions are aligned with international standards for identity and biometrics.

  1. Technical Requirements

Algorithms and key sizes: use ECDSA P-256 and SHA-256 for signatures and certificates, ensuring compatibility and longevity.

Signed objects and OIDs: critical data must be encapsulated and signed in CMS, preserving traceability and future verifiability.

Integration with CMS/IDMS: the identity management chain requires secure interaction between the Identity Management System (IDMS), the Card Management System (CMS), and cryptographic modules (HSM).

  1. Data to Capture

Demographic data:

Full name

Unique identification number

Nationality

Postal address

Phone number

Biometric data:

Fingerprints: at least two mandatory, with optional ten-fingerprint capture

Electronic facial image according to international standards

Left and right iris images

Capture metadata: device, operator, quality, date and time

  1. Logical Model of the Intelligent Container

The identity container must be structured into well-defined sections:

{
"header": {
"uuid": "",
"enrolment_time": "",
"issuer": "",
"version": "1.0"
},
"demographics": { ... },
"biometrics": {
"fingerprints": [ ... ],
"face": { ... },
"iris": [ ... ]
},
"keys_and_certs": { ... },
"pin_policy": { ... },
"audit": [ ... ],
"integrity": {
"hash": "",
"signed_object": ""
}
}

  1. Enrollment Flow

Step 0 — Preparation: define policies, retention rules, PIN/PUK limits, and configure the HSM/CA.
Step 1 — Physical identity verification: collect breeder documents, register the process, and store only secure references.
Step 2 — Biometric capture: collect fingerprints, face, and iris following ISO standards; record quality scores and repeat if below threshold.
Step 3 — Key generation: preferably on an HSM or on-card; issue associated X.509 certificates.
Step 4 — Container construction: serialize in canonical format and compute SHA3-256 hash.
Step 5 — Container signing: apply ECDSA-P256 signature encapsulated in CMS.
Step 6 — Card personalization: write objects via secure GlobalPlatform channel, store certificates and keys.
Step 7 — PIN/PUK/TOTP provisioning: set on-card static PIN, optional TOTP, and retry counter policy.
Step 8 — Delivery and audit: register card handover, store hash and signature of container in a secure repository.

  1. Cryptographic Design

Use ECDSA P-256 and SHA-256 for container signatures.

Sign critical objects such as biometrics and identity data.

Custody of keys and secrets in HSM or PKCS#11 modules.

Secure channel communication between IDMS, CMS, and card.

  1. Code: Container Creation and Signature # create_and_sign_container.py # Author: Antonio José Socorro Marín © 2025

import json
import base64
from datetime import datetime
import hashlib
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec

def canonical_json_bytes(obj):
return json.dumps(obj, sort_keys=True, separators=(',',':'), ensure_ascii=False).encode('utf-8')

def sha3_256_hex(data_bytes):
h = hashlib.sha3_256()
h.update(data_bytes)
return h.hexdigest()

def generate_demo_ecdsa_key():
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()
return private_key, public_key

def sign_bytes_ecdsa_sha256(private_key, data_bytes):
signature_der = private_key.sign(data_bytes, ec.ECDSA(hashes.SHA256()))
return base64.b64encode(signature_der).decode('ascii')

def build_container(demo_identity):
header = {
"uuid": demo_identity.get("uuid"),
"enrolment_time": datetime.utcnow().isoformat() + "Z",
"issuer": "Authority CN=IDIssuer",
"version": "1.0"
}
container = {
"header": header,
"demographics": demo_identity.get("demographics"),
"biometrics": demo_identity.get("biometrics"),
"keys_and_certs": demo_identity.get("keys_and_certs", {}),
"pin_policy": demo_identity.get("pin_policy", {}),
"audit": demo_identity.get("audit", [])
}
return container

if name == "main":
demo_identity = {
"uuid": "b7f6a2d6-3f7a-4a8f-ab12-0f4e6b1a9c2d",
"demographics": {
"given_name": "Juan",
"family_name": "Pérez",
"id_number": "ID12345678",
"nationality": "VEN",
"address": "Caracas, Venezuela",
"phone": "+58-412-1234567"
},
"biometrics": {
"fingerprints": [
{ "type":"ISO19794-2", "template":"", "quality":98 },
{ "type":"ISO19794-2", "template":"", "quality":96 }
],
"face": { "format":"ISO19794-5", "image":"", "quality":92 },
"iris": [
{ "format":"ISO19794-6","template":"" },
{ "format":"ISO19794-6","template":"" }
]
},
"pin_policy": {
"static_pin_length": 6,
"otp_enabled": True,
"puk_present": True
},
"audit": []
}

container = build_container(demo_identity)
canonical = canonical_json_bytes(container)
container_hash = sha3_256_hex(canonical)
container["integrity"] = { "hash": container_hash, "hash_alg": "SHA3-256" }

priv, pub = generate_demo_ecdsa_key()
signature_b64 = sign_bytes_ecdsa_sha256(priv, canonical)
container["integrity"]["signed"] = { "alg": "ECDSA-P256-SHA256", "signature_b64": signature_b64, "signer": "CN=IDIssuer" }

print(json.dumps(container, indent=2, ensure_ascii=False))
Enter fullscreen mode Exit fullscreen mode
  1. Dynamic PIN and Multi-Factor

The system must include:

Static PIN: verified on-card, minimum length 6 digits, retry counter, blocking, and PUK.

Dynamic PIN (OTP): TOTP implementation, 6 digits with ±30 s time window.

Biometric-derived PIN: numeric PIN calculated using HMAC-SHA256 over the biometric template hash and a nonce, without exposing raw biometric data.

Code: Biometric-derived PIN

biometric_derived_pin.py

Author: Antonio José Socorro Marín © 2025

import hmac, hashlib, binascii

def derive_pin_from_biometric(template_hash_hex, secret_hmac_key, nonce_int, digits=6):
template_bytes = binascii.unhexlify(template_hash_hex)
nonce_bytes = nonce_int.to_bytes(8, 'big')
mac = hmac.new(secret_hmac_key, template_bytes + nonce_bytes, hashlib.sha256).digest()
code_int = int.from_bytes(mac[-4:], 'big') & 0x7FFFFFFF
pin = str(code_int % (10 ** digits)).zfill(digits)
return pin

  1. Audit and Future Verification

Each container must include a SHA3-256 hash and ECDSA-P256 signature.

Enrollment, capture, and personalization logs must be preserved in sealed evidence repositories.

Full traceability should be implemented for future verification and audits.

  1. Operational Recommendations

Perform all critical operations (signing, secret custody) in HSM.

Align biometric data formats with ISO/IEC 19794 standards.

Segregate roles: enrollment, PKI management, and personalization must remain separate.

Apply privacy by design: store only necessary data and encrypt all sensitive content.

Define metrics and run regular quality and verification tests.

  1. Conclusion

This first module establishes the foundation for a secure, signed, and verifiable identity container capable of storing demographic and biometric data in accordance with international standards. This design will serve as the baseline for subsequent phases of the system, including the generation of securely exportable derived identities that can be verified across any compatible infrastructure.

Top comments (0)