Skip to main content
QMSQMS
QMS
  • Welcome to your QMS
  • Quality Manual
  • Procedures
    • GP-001 Control of documents
    • GP-002 Quality planning
    • GP-003 Audits
    • GP-004 Vigilance system
    • GP-005 Human Resources and Training
    • GP-006 Non-conformity, Corrective and Preventive actions
    • GP-007 Post-market surveillance
    • GP-008 Product requirements
    • GP-009 Sales
    • GP-010 Purchases and suppliers evaluation
    • GP-011 Provision of service
    • GP-012 Design, redesign and development
    • GP-013 Risk management
    • GP-014 Feedback and complaints
    • GP-015 Clinical evaluation
    • GP-016 Traceability and identification
    • GP-017 Technical assistance service
    • GP-018 Infrastructure and facilities
    • GP-019 Software validation plan
    • GP-020 QMS Data analysis
    • GP-021 Communications
    • GP-022 Document translation
    • GP-023 Change control management
    • GP-024 Predetermined Change Control Plan
    • GP-025 Usability and Human Factors Engineering
    • GP-027 Corporate Governance
    • GP-028 AI Development
    • GP-029 Software Delivery And Comissioning
    • GP-050 Data Protection
    • GP-051 Security violations
    • GP-052 Data Privacy Impact Assessment (DPIA)
    • GP-100 Business Continuity (BCP) and Disaster Recovery plans (DRP)
    • GP-101 Information security
    • GP-200 Remote Data Acquisition in Clinical Investigations
    • GP-026 Market-specific product requirements
    • GP-110 Esquema Nacional de Seguridad
      • ORG Marco organizativo
      • OP Marco operacional
        • OP.PL Planificación
        • OP.ACC Control de acceso
        • OP.EXP Explotación
          • OP.EXP.1 Inventario de activos
          • OP.EXP.10 Protección de los registros de actividad
          • OP.EXP.11 Protección de las claves criptográficas
          • OP.EXP.2 Configuración de seguridad
          • OP.EXP.3 Gestión de la configuración
          • OP.EXP.4 Mantenimiento
          • OP.EXP.5 Gestión de Cambios - Procedimiento Formal ENS
          • OP.EXP.6 Protección frente a código dañino
          • OP.EXP.7 Gestión de incidentes
          • OP.EXP.8 Registro de la actividad de los usuarios
          • OP.EXP.9 Registro de la gestión de incidentes
        • OP.EXT Servicios externos
        • OP.NUB Servicios en la nube
        • OP.CONT Continuidad del servicio
        • OP.MON Monitorización del sistema
      • MP Medidas de protección
      • Sin asignar
      • Real Decreto 311/2022, de 3 de mayo, por el que se regula el Esquema Nacional de Seguridad.
  • Records
  • Legit.Health Plus Version 1.1.0.0
  • Legit.Health Plus Version 1.1.0.1
  • Licenses and accreditations
  • Applicable Standards and Regulations
  • Public tenders
  • Procedures
  • GP-110 Esquema Nacional de Seguridad
  • OP Marco operacional
  • OP.EXP Explotación
  • OP.EXP.11 Protección de las claves criptográficas

OP.EXP.11 Protección de las claves criptográficas

Documentos de referencia​

Referencias normativas ENS​

  • Real Decreto 311/2022 - Anexo II, Medida OP.EXP.11
  • CCN-STIC-807 - Criptología de empleo en el ENS
  • CCN-STIC-804 - Guía de Implantación del ENS
  • CCN-STIC-822 - Guía para la Configuración Segura de Sistemas

Documentación interna Legit Health​

  • T-024-018 - Procedimiento de gestión de claves criptográficas
  • T-024-019 - Política de uso de criptografía
  • T-024-020 - Inventario de claves y certificados
  • R-110-003 - Inventario de claves criptográficas ENS
  • GP-013 - Gestión de Ciberseguridad
  • T-110-007 - Matriz RACI de seguridad ENS
  • T-110-008 - Procedimiento de notificación CCN-CERT

Referencias internacionales​

  • ISO/IEC 27001:2022 - Control A.8.24 (Uso de criptografía)
  • NIST SP 800-57 - Recomendaciones para gestión de claves
  • FIPS 140-2 - Módulos criptográficos
  • Common Criteria - Evaluación de seguridad

Referencias médicas​

  • IEC 62304:2015 - Procesos de ciclo de vida del software de dispositivos médicos
  • ISO 14971:2019 - Gestión de riesgos para dispositivos médicos
  • MDR 2017/745 - Reglamento de Dispositivos Médicos
  • FDA Cybersecurity Guidance - Orientación de ciberseguridad para dispositivos médicos

Guía de implantación​

Objetivo​

Establecer un sistema integral de protección, gestión y control del ciclo de vida completo de todas las claves criptográficas utilizadas en los sistemas de Legit Health, garantizando la seguridad del dispositivo médico y el cumplimiento de los requisitos regulatorios.

Alcance​

Este procedimiento aplica a:

  • Claves de cifrado de datos (AES, ChaCha20)
  • Claves de firma digital (RSA, ECDSA, EdDSA)
  • Certificados digitales (SSL/TLS, firma de código)
  • Claves de autenticación (API keys, tokens)
  • Secretos de aplicación (passwords, connection strings)
  • Claves de cifrado de base de datos
  • Material criptográfico del dispositivo médico
  • Claves de backup y recuperación

Arquitectura de gestión de claves​

3.1 Componentes del sistema​

┌─────────────────────────────────────────┐
│ Hardware Security Module (HSM) │
│ FIPS 140-2 Level 3 Certified │
└───────────────────┬─────────────────────┘
│
┌────────────┴────────────┐
│ Key Management Service │
│ (AWS KMS / Azure) │
└───────┬─────────┬───────┘
│ │
┌─────────┴───┐ ┌───┴──────────┐
│ Secrets Vault │ │ Certificate │
│ (HashiCorp) │ │ Manager │
└─────────────┘ └──────────────┘

3.2 Jerarquía de claves​

Master Key (HSM):
├─ Key Encryption Keys (KEK):
│ ├─ Data Encryption Keys (DEK)
│ ├─ Database Encryption Keys
│ └─ Backup Encryption Keys
│
├─ Signing Keys:
│ ├─ Code Signing Certificates
│ ├─ Document Signing Keys
│ └─ API Request Signing
│
└─ Authentication Keys:
├─ TLS/SSL Certificates
├─ SSH Keys
└─ Service Account Keys

Ciclo de vida de las claves​

4.1 Generación de claves​

Requisitos de generación:

def generate_cryptographic_key(key_type, purpose):
# Validar parámetros
validate_key_parameters(key_type, purpose)

# Configuración según tipo
if key_type == "SYMMETRIC":
key_spec = {
"algorithm": "AES",
"key_size": 256, # Bits
"mode": "GCM",
"source": "HSM"
}
elif key_type == "ASYMMETRIC":
key_spec = {
"algorithm": "RSA",
"key_size": 4096, # Bits mínimo
"padding": "OAEP",
"hash": "SHA-256"
}
elif key_type == "ELLIPTIC":
key_spec = {
"algorithm": "ECDSA",
"curve": "P-384", # secp384r1
"hash": "SHA-384"
}

# Generar con HSM/KMS
key = kms_client.generate_data_key(
KeyId=master_key_id,
KeySpec=key_spec,
EncryptionContext={'purpose': purpose}
)

# Registrar en inventario
register_key_metadata(key, purpose)

return key

Estándares mínimos:

TipoAlgoritmoTamaño mínimoUso
SimétricoAES-GCM256 bitsCifrado de datos
AsimétricoRSA4096 bitsFirma, key exchange
ElípticaECDSAP-384Firma digital
HashSHASHA-384Integridad
KDFPBKDF2100,000 iterDerivación

4.2 Distribución segura​

Mecanismos de distribución:

  1. Distribución automatizada (preferida):
Automated Distribution:
Method: Secrets Manager API
Authentication: IAM Role + MFA
Transport: TLS 1.3
Audit: CloudTrail enabled
Rotation: Automatic triggers
  1. Distribución manual (excepcional):
Manual Distribution:
Approval: CISO + Key Custodian
Method: Secure courier / HSM card
Envelope: Split knowledge (2 personas)
Verification: Out-of-band confirmation
Documentation: Chain of custody

Protocolo de intercambio seguro:

def secure_key_exchange(recipient_public_key, key_to_share):
# Generar clave efímera
ephemeral_key = generate_ephemeral_key()

# ECDH para secreto compartido
shared_secret = ecdh(
ephemeral_key.private,
recipient_public_key
)

# Derivar clave de cifrado
encryption_key = hkdf(
shared_secret,
salt=generate_random_salt(),
info=b"key-exchange",
length=32
)

# Cifrar clave a compartir
encrypted_key = aes_gcm_encrypt(
key_to_share,
encryption_key
)

# Firmar el paquete
signature = sign_data(
encrypted_key + ephemeral_key.public
)

return {
'encrypted_key': encrypted_key,
'ephemeral_public': ephemeral_key.public,
'signature': signature
}

4.3 Almacenamiento seguro​

Opciones de almacenamiento por tipo:

Production Keys:
Location: HSM / AWS KMS
Access: Role-based + MFA
Backup: HSM cluster replication
Audit: Every access logged

Development Keys:
Location: HashiCorp Vault
Access: Developer role + approval
Backup: Encrypted in S3
Rotation: Monthly

Certificates:
Location: AWS Certificate Manager
Access: Service accounts only
Renewal: Auto (30 days before expiry)
Validation: DNS/Email

Secrets/Passwords:
Location: AWS Secrets Manager
Access: Application roles
Rotation: Every 90 days
Versioning: Last 5 versions

Protección en memoria:

// Protección contra memory dumps
void protect_key_in_memory(void *key, size_t key_len) {
// Marcar página como no-swappable
mlock(key, key_len);

// Marcar como solo lectura cuando no esté en uso
mprotect(key, key_len, PROT_READ);

// Limpiar después de uso
explicit_bzero(key, key_len);

// Liberar lock
munlock(key, key_len);
}

4.4 Uso de claves​

Control de uso:

class KeyUsageController:
def __init__(self):
self.usage_limits = {
'encryption': 1000000, # Operations
'signing': 100000,
'time_limit': 365 * 24 * 3600 # Seconds
}

def authorize_key_use(self, key_id, operation):
# Verificar permisos
if not has_permission(current_user, key_id, operation):
raise PermissionError("Unauthorized key usage")

# Verificar límites
if exceeded_usage_limit(key_id):
trigger_key_rotation(key_id)
raise LimitExceeded("Key usage limit reached")

# Verificar propósito
if not matches_key_purpose(key_id, operation):
raise PurposeViolation("Key used for wrong purpose")

# Registrar uso
log_key_usage(key_id, operation, current_user)

return True

Separación de propósitos:

  • Claves de cifrado NUNCA para firma
  • Claves de producción NUNCA en desarrollo
  • Claves de backup SOLO para recuperación
  • Claves de usuario NUNCA para servicios

4.5 Rotación de claves​

Calendario de rotación completo según ENS:

Tipo de claveENS BásicoENS MedioENS AltoRotación forzadaUso máximo
Master Keys (HSM)2 años1 año6 mesesCompromiso sospechadoN/A
Key Encryption Keys (KEK)1 año6 meses3 mesesLímite de uso alcanzado100M operaciones
Data Encryption Keys (DEK)6 meses90 días30 días1M de operaciones10M operaciones
TLS Certificates1 año90 días90 díasCambio de dominioN/A
Code Signing Certificates2 años1 año1 añoCompromiso de clave privadaN/A
API Keys (Aplicación)6 meses90 días30 díasEmpleado desvinculadoN/A
Service Account Keys1 año6 meses90 díasServicio descomisionadoN/A
Database Encryption Keys6 meses3 meses1 mesBrecha detectada50M transacciones
SSH Keys (Admin)1 año6 meses3 mesesAcceso anómaloN/A
SSH Keys (Service)2 años1 año6 mesesCambio de infraestructuraN/A
Backup Encryption Keys1 año6 meses3 mesesBackup comprometidoN/A

Rotación automatizada por tipo de clave:

class ENSKeyRotationScheduler:
"""
Planificador de rotación de claves según niveles ENS
"""

def __init__(self, ens_level: str):
self.ens_level = ens_level
self.rotation_schedules = self._load_ens_schedules()
self.emergency_triggers = self._load_emergency_triggers()

def create_rotation_schedule(self, key_inventory: list) -> dict:
"""
Crear calendario completo de rotación
"""

schedule = {
'daily': [],
'weekly': [],
'monthly': [],
'quarterly': [],
'annually': []
}

for key_info in key_inventory:
key_type = key_info['type']
creation_date = key_info['created']

# Obtener frecuencia según tipo y nivel ENS
rotation_freq = self.rotation_schedules[self.ens_level][key_type]

# Calcular próxima rotación
next_rotation = creation_date + rotation_freq

# Agregar buffer de seguridad (rotar 7 días antes)
next_rotation_safe = next_rotation - timedelta(days=7)

# Clasificar en cronograma
days_until = (next_rotation_safe - datetime.now()).days

if days_until <= 1:
schedule['daily'].append({
'key_id': key_info['id'],
'type': key_type,
'priority': 'urgent',
'deadline': next_rotation_safe
})
elif days_until <= 7:
schedule['weekly'].append({
'key_id': key_info['id'],
'type': key_type,
'priority': 'high',
'deadline': next_rotation_safe
})
elif days_until <= 30:
schedule['monthly'].append({
'key_id': key_info['id'],
'type': key_type,
'priority': 'medium',
'deadline': next_rotation_safe
})
elif days_until <= 90:
schedule['quarterly'].append({
'key_id': key_info['id'],
'type': key_type,
'priority': 'low',
'deadline': next_rotation_safe
})
else:
schedule['annually'].append({
'key_id': key_info['id'],
'type': key_type,
'priority': 'maintenance',
'deadline': next_rotation_safe
})

return schedule

def execute_scheduled_rotations(self, schedule_period: str) -> list:
"""
Ejecutar rotaciones programadas
"""

schedule = self.get_current_schedule()
rotations_to_execute = schedule.get(schedule_period, [])

results = []

for rotation in rotations_to_execute:
try:
# Validar prerrequisitos
self.validate_rotation_prerequisites(rotation['key_id'])

# Ejecutar rotación
result = self.execute_key_rotation(rotation)

# Validar post-rotación
self.validate_post_rotation(result['new_key_id'])

results.append({
'key_id': rotation['key_id'],
'status': 'success',
'new_key_id': result['new_key_id'],
'completion_time': datetime.now()
})

except Exception as e:
results.append({
'key_id': rotation['key_id'],
'status': 'failed',
'error': str(e),
'retry_scheduled': datetime.now() + timedelta(hours=4)
})

# Alertar al equipo de seguridad
self.alert_rotation_failure(rotation['key_id'], e)

# Generar informe de rotaciones
self.generate_rotation_report(results)

return results

Matriz de rotación de claves médicas:

Medical_Device_Key_Rotation:
Patient_Data_Keys:
rotation_frequency: "monthly"
pre_rotation_validation:
- patient_data_backup_verified
- clinical_workflow_coordination
- off_hours_scheduling
post_rotation_validation:
- data_accessibility_test
- clinical_system_integration_test
- performance_impact_assessment

AI_Model_Signing_Keys:
rotation_frequency: "annually"
regulatory_coordination:
- notify_competent_authorities: "30_days_prior"
- clinical_validation_required: true
- version_control_update: true
post_rotation_validation:
- model_signature_verification
- clinical_accuracy_validation
- regulatory_compliance_check

Device_Communication_Keys:
rotation_frequency: "quarterly"
deployment_strategy: "gradual_rollout"
rollback_capability: true
monitoring_period: "48_hours"

Proceso de rotación automatizada:

def rotate_key_automated(key_id):
try:
# 1. Generar nueva clave
new_key = generate_new_key(get_key_spec(key_id))

# 2. Fase de transición (ambas claves activas)
activate_key(new_key, mode='transition')

# 3. Re-cifrar datos gradualmente
schedule_reencryption_job({
'old_key': key_id,
'new_key': new_key.id,
'batch_size': 1000,
'priority': 'background'
})

# 4. Monitorear progreso
while not reencryption_complete():
time.sleep(300) # Check every 5 min
log_progress()

# 5. Desactivar clave antigua
deactivate_key(key_id)

# 6. Archivar para auditoría
archive_key(key_id, retention_years=7)

# 7. Notificar completación
notify_key_rotation_complete(key_id, new_key.id)

except Exception as e:
rollback_key_rotation(key_id)
alert_security_team(e)
raise

4.6 Destrucción de claves​

Procedimiento de destrucción segura:

def secure_key_destruction(key_id):
# 1. Verificar que no hay datos dependientes
if has_dependent_data(key_id):
raise DependencyError("Cannot destroy key with dependent data")

# 2. Obtener aprobaciones necesarias
approvals = get_destruction_approvals(key_id)
if len(approvals) < 2:
raise ApprovalError("Insufficient approvals for destruction")

# 3. Backup final para cumplimiento
create_compliance_archive(key_id)

# 4. Destrucción criptográfica
# Sobrescribir múltiples veces
for i in range(7): # DoD 5220.22-M standard
overwrite_key_material(key_id, pattern=OVERWRITE_PATTERNS[i])

# 5. Eliminar de todos los sistemas
remove_from_hsm(key_id)
remove_from_kms(key_id)
remove_from_vault(key_id)
remove_from_backups(key_id)

# 6. Verificar destrucción
if key_still_exists(key_id):
raise DestructionError("Key destruction incomplete")

# 7. Certificado de destrucción
certificate = generate_destruction_certificate({
'key_id': key_id,
'timestamp': datetime.utcnow(),
'method': 'crypto_shredding',
'approvers': approvals,
'verified_by': current_user
})

# 8. Registro permanente
log_key_destruction(certificate)

return certificate

Controles de seguridad específicos​

5.1 Segregación de funciones​

Roles y responsabilidades:
Key_Administrator:
- Crear políticas de claves
- Aprobar generación de master keys
- Auditar uso de claves
- NO puede: Usar claves directamente

Key_Custodian:
- Generar claves operacionales
- Distribuir claves autorizadas
- Rotar claves según calendario
- NO puede: Modificar políticas

Key_User:
- Usar claves asignadas
- Solicitar nuevas claves
- Reportar incidentes
- NO puede: Compartir o exportar claves

Key_Auditor:
- Revisar logs de uso
- Verificar cumplimiento
- Investigar anomalías
- NO puede: Modificar claves o políticas

5.1bis Directrices de Uso de HSM según CCN-STIC-807​

Configuración HSM para cumplimiento ENS:

HSM_Configuration_ENS:
Certification_Level: FIPS 140-2 Level 3 (mínimo)

Approved_Algorithms_Basic:
Symmetric:
- AES-256 (GCM, CBC)
- ChaCha20-Poly1305
Asymmetric:
- RSA-4096 (OAEP, PSS)
- ECDSA P-256, P-384
Hash:
- SHA-256, SHA-384, SHA-512

Approved_Algorithms_Medium:
Symmetric:
- AES-256 (GCM obligatorio)
Asymmetric:
- RSA-4096 (obligatorio)
- ECDSA P-384 (recomendado)
Hash:
- SHA-384 (mínimo)

Approved_Algorithms_High:
Symmetric:
- AES-256-GCM (obligatorio)
Asymmetric:
- RSA-4096 con OAEP SHA-384
- ECDSA P-521
Hash:
- SHA-512 (obligatorio)

Procedimientos HSM específicos para dispositivos médicos:

class MedicalDeviceHSMManager:
"""
Gestión especializada de HSM para dispositivos médicos
según IEC 62304 y MDR requisitos de ciberseguridad
"""

def __init__(self):
self.medical_key_policies = {
'patient_data_encryption': {
'algorithm': 'AES-256-GCM',
'key_derivation': 'HKDF-SHA384',
'rotation_frequency': timedelta(days=30),
'backup_requirement': 'geographic_redundancy',
'audit_level': 'detailed',
'fda_compliance': True
},
'diagnostic_algorithm_signing': {
'algorithm': 'ECDSA-P384',
'hash_function': 'SHA-384',
'rotation_frequency': timedelta(days=365),
'code_signing_cert': True,
'regulatory_approval': 'required_before_use'
},
'device_authentication': {
'algorithm': 'ECDSA-P256',
'certificate_validity': timedelta(days=730),
'mutual_tls': True,
'device_identity_binding': 'hardware_secure_element'
}
}

def generate_medical_device_key(self, purpose: str, device_class: str) -> dict:
"""
Genera claves específicas para dispositivos médicos
"""

if purpose not in self.medical_key_policies:
raise ValueError(f"Unknown medical purpose: {purpose}")

policy = self.medical_key_policies[purpose]

# Validar clasificación de dispositivo médico
if device_class in ['Class_IIa', 'Class_IIb', 'Class_III']:
# Requerir aprobación adicional para dispositivos de alto riesgo
if not self.validate_regulatory_approval(purpose, device_class):
raise ComplianceError("Regulatory approval required")

# Generar clave con parámetros específicos médicos
key_spec = {
'algorithm': policy['algorithm'],
'purpose': f"medical_{purpose}",
'device_class': device_class,
'regulatory_context': {
'mdr_compliance': True,
'fda_guidance': True,
'patient_safety': True
},
'key_attributes': {
'non_repudiation': True,
'key_recovery_escrow': device_class in ['Class_III'],
'audit_trail': 'comprehensive',
'geographic_restrictions': None # Global deployment
}
}

# Usar HSM dedicado para dispositivos médicos
medical_hsm = self.get_medical_hsm_partition()
key = medical_hsm.generate_key(key_spec)

# Registrar en inventario de dispositivos médicos
self.register_medical_key(key, device_class, purpose)

# Crear evidencias de cumplimiento
self.generate_compliance_evidence(key, device_class)

return key

def implement_medical_key_rotation(self, key_id: str, emergency: bool = False) -> dict:
"""
Rotación de claves para dispositivos médicos con consideraciones especiales
"""

key_info = self.get_medical_key_info(key_id)

# Validar impacto en dispositivos desplegados
deployed_devices = self.get_deployed_devices_using_key(key_id)

if len(deployed_devices) > 0 and not emergency:
# Planificar rotación gradual
rotation_plan = self.create_gradual_rotation_plan(deployed_devices)

# Notificar a autoridades regulatorias si es necesario
if self.requires_regulatory_notification(key_info):
self.notify_regulatory_authorities(key_id, rotation_plan)

# Coordinar con equipos clínicos
self.coordinate_clinical_rotation(rotation_plan)

# Ejecutar rotación
new_key = self.execute_medical_key_rotation(key_id, emergency)

# Validar que dispositivos funcionan con nueva clave
self.validate_post_rotation_functionality(deployed_devices, new_key)

# Documentar para auditorías regulatorias
self.document_medical_key_rotation(key_id, new_key, deployed_devices)

return new_key

Configuración de HSM por nivel de seguridad ENS:

HSM_Security_Levels:
Basic_Level:
hsm_partition: "legit-health-basic"
authentication: "password + smart_card"
key_backup: "encrypted_export"
audit_frequency: "monthly"

Medium_Level:
hsm_partition: "legit-health-medium"
authentication: "dual_authentication + biometric"
key_backup: "hsm_replication + encrypted_export"
audit_frequency: "weekly"
tamper_response: "immediate_zeroization"

High_Level:
hsm_partition: "legit-health-high"
authentication: "triple_authentication + biometric + pin"
key_backup: "hsm_cluster + geographic_redundancy"
audit_frequency: "daily"
tamper_response: "immediate_zeroization + alert"
physical_security: "24x7_monitoring + dual_custody"
network_isolation: "dedicated_vlan + firewall"

5.2 Control de acceso dual​

Operaciones críticas con control dual:

  • Generación de master keys
  • Exportación de claves
  • Destrucción de claves
  • Cambio de políticas de seguridad
  • Acceso a HSM físico
def dual_control_operation(operation, params):
# Solicitar primera autorización
auth1 = request_authorization(
user=params['initiator'],
operation=operation
)

# Solicitar segunda autorización (diferente persona)
auth2 = request_authorization(
user=params['approver'],
operation=operation,
exclude=[params['initiator']]
)

# Verificar ambas autorizaciones
if verify_dual_auth(auth1, auth2):
# Ejecutar con ventana de tiempo limitada
with time_limited_execution(minutes=30):
result = execute_operation(operation, params)
audit_dual_control(operation, auth1, auth2, result)
return result
else:
raise DualControlError("Dual authorization failed")

5.3 Escrow de claves​

Procedimiento de escrow (solo claves críticas):

Key Escrow Process:
Eligible_Keys:
- Master encryption keys
- Disaster recovery keys
- Legal hold keys

Escrow_Method:
- Split: Shamir's Secret Sharing (3 of 5)
- Storage:
- Fragment 1: Bank safe deposit box
- Fragment 2: Legal firm
- Fragment 3: Executive safe
- Fragment 4: External auditor
- Fragment 5: Cloud backup (encrypted)

Recovery_Process:
- Requires: CEO + CFO + Legal approval
- Witnesses: External auditor
- Documentation: Notarized
- Verification: Multi-party video call

Protección física de material criptográfico​

6.1 HSM físico​

Physical Security:
Location: Secure datacenter cage
Access: Biometric + smartcard
Monitoring: 24/7 CCTV
Environmental:
- Temperature: 18-22°C
- Humidity: 45-55%
- Fire suppression: FM-200
Tamper_Protection:
- Mesh sensor
- Zeroization on tamper
- Audit log to remote system

6.2 Transporte de material criptográfico​

Protocolo de transporte seguro:

  1. Doble contenedor sellado
  2. Courier bonificado con seguro
  3. Tracking GPS en tiempo real
  4. Verificación de integridad en destino
  5. Destrucción de contenedores usados

Gestión de certificados digitales​

7.1 Infraestructura PKI​

PKI Architecture:
Root_CA:
- Offline HSM
- 20 year validity
- RSA 4096 / ECC P-521

Intermediate_CA:
- Online HSM
- 10 year validity
- Issues end-entity certs

Certificate_Types:
- TLS/SSL: 90 days auto-renewal
- Code Signing: 1 year
- Email (S/MIME): 1 year
- Device: 2 years
- User Auth: 1 year

7.2 Ciclo de vida de certificados​

class CertificateLifecycle:
def __init__(self):
self.renewal_threshold = 30 # days before expiry

def monitor_certificates(self):
for cert in get_all_certificates():
days_to_expiry = (cert.not_after - datetime.now()).days

if days_to_expiry < 0:
alert_expired_certificate(cert)
disable_certificate(cert)

elif days_to_expiry < self.renewal_threshold:
if cert.auto_renew:
self.auto_renew_certificate(cert)
else:
notify_manual_renewal_required(cert)

elif days_to_expiry < 60:
send_expiry_warning(cert)

def auto_renew_certificate(self, cert):
# Generar CSR
csr = generate_csr(cert.subject, cert.key_spec)

# Solicitar nuevo certificado
new_cert = ca.issue_certificate(csr)

# Instalar con overlap period
install_certificate(new_cert, overlap_days=7)

# Programar desactivación del antiguo
schedule_deactivation(cert, days=7)

Auditoría y cumplimiento​

8.1 Registros de auditoría​

Eventos registrados según ENS:

{
"timestamp": "2025-08-29T10:30:00Z",
"event_type": "KEY_GENERATION",
"key_id": "arn:aws:kms:key/12345",
"ens_classification": "MEDIO",
"algorithm": "AES-256-GCM",
"purpose": "patient_data_encryption",
"medical_context": {
"device_class": "Class_IIa",
"patient_impact": "direct",
"regulatory_requirement": "MDR_Article_17"
},
"requestor": {
"user_id": "admin@legithealth.com",
"role": "key_custodian",
"authentication_level": "mfa_biometric"
},
"approver": {
"user_id": "security@legithealth.com",
"role": "key_administrator",
"approval_method": "dual_control"
},
"source_context": {
"ip_address": "10.0.1.50",
"location": "Madrid_DC_Primary",
"session_id": "sess_abc123"
},
"hsm_details": {
"serial_number": "HSM-001",
"partition": "legit-health-medium",
"firmware_version": "7.4.2",
"fips_level": "Level_3"
},
"result": "SUCCESS",
"compliance_metadata": {
"ccn_stic_807_compliant": true,
"key_length": 256,
"expiry": "2025-11-29T10:30:00Z",
"rotation_schedule": "30_days",
"backup_created": true,
"escrow_required": false,
"audit_retention": "7_years"
},
"integration_references": {
"risk_assessment": "R-TF-013-002",
"threat_model": "T-024-006",
"ens_control": "OP.EXP.11"
}
}

Eventos adicionales para dispositivos médicos:

Medical_Device_Specific_Events:
CLINICAL_KEY_USAGE:
description: "Uso de claves en contexto clínico"
mandatory_fields:
- patient_anonymized_id
- clinical_procedure
- healthcare_provider
- diagnostic_accuracy_impact

REGULATORY_NOTIFICATION:
description: "Notificación a autoridades regulatorias"
mandatory_fields:
- competent_authority
- notification_type
- regulatory_deadline
- compliance_status

KEY_ESCROW_ACCESS:
description: "Acceso a claves en escrow"
mandatory_fields:
- legal_justification
- court_order_reference
- witness_list
- data_subjects_affected

8.1bis Inventario Completo de Claves Criptográficas​

Template de inventario según RD 311/2022:

class ENSCryptographicInventory:
"""
Inventario completo de material criptográfico según ENS
"""

def generate_ens_inventory(self) -> dict:
"""
Genera inventario completo para auditoría ENS
"""

inventory = {
'metadata': {
'generation_date': datetime.now().isoformat(),
'ens_level': 'MEDIO',
'organization': 'Legit Health S.L.',
'system_category': 'Dispositivo Médico Clase IIa',
'audit_period': self.get_audit_period(),
'compliance_framework': ['ENS', 'MDR', 'ISO_27001']
},
'summary': {
'total_keys': 0,
'active_keys': 0,
'expired_keys': 0,
'keys_due_rotation': 0,
'hsm_keys': 0,
'software_keys': 0,
'compliance_score': 0.0
},
'key_categories': {},
'compliance_gaps': [],
'recommendations': []
}

# Obtener todas las claves por categoría
categories = [
'master_keys',
'patient_data_keys',
'ai_model_keys',
'communication_keys',
'backup_keys',
'administrative_keys'
]

for category in categories:
keys = self.get_keys_by_category(category)
inventory['key_categories'][category] = self.analyze_key_category(keys)
inventory['summary']['total_keys'] += len(keys)

# Evaluar cumplimiento
inventory['compliance_gaps'] = self.identify_compliance_gaps()
inventory['compliance_score'] = self.calculate_compliance_score()
inventory['recommendations'] = self.generate_recommendations()

return inventory

def analyze_key_category(self, keys: list) -> dict:
"""
Analiza una categoría específica de claves
"""

analysis = {
'count': len(keys),
'algorithms': {},
'key_strengths': {},
'rotation_status': {
'current': 0,
'due_soon': 0,
'overdue': 0
},
'storage_locations': {},
'compliance_issues': []
}

for key in keys:
# Algoritmos utilizados
algo = key.get('algorithm', 'unknown')
analysis['algorithms'][algo] = analysis['algorithms'].get(algo, 0) + 1

# Fortaleza de claves
strength = self.assess_key_strength(key)
analysis['key_strengths'][strength] = analysis['key_strengths'].get(strength, 0) + 1

# Estado de rotación
rotation_status = self.assess_rotation_status(key)
analysis['rotation_status'][rotation_status] += 1

# Ubicación de almacenamiento
location = key.get('storage_location', 'unknown')
analysis['storage_locations'][location] = analysis['storage_locations'].get(location, 0) + 1

# Identificar problemas de cumplimiento
issues = self.identify_key_compliance_issues(key)
analysis['compliance_issues'].extend(issues)

return analysis

Registro R-110-003 - Inventario de Claves Criptográficas:

# R-110-003 Inventario de Claves Criptográficas ENS

## Información General

- **Fecha de inventario**: 29 de agosto de 2025
- **Período de auditoría**: Q3 2025
- **Responsable**: Administrador de Claves ENS
- **Nivel de clasificación**: CONFIDENCIAL

## Resumen Ejecutivo

| Métrica | Valor | Estado |
| ------------------------------------ | --------- | ------ |
| Total de claves activas | 247 | ✅ |
| Claves próximas a rotación (30 días) | 12 | ⚠️ |
| Claves vencidas | 0 | ✅ |
| Cumplimiento CCN-STIC-807 | 98.8% | ✅ |
| Claves en HSM | 156 (63%) | ✅ |
| Algoritmos no aprobados | 0 | ✅ |

## Inventario por Categoría

### Claves Maestras (HSM)

| ID | Algoritmo | Creación | Próxima Rotación | Uso | Estado |
| ------ | --------- | ---------- | ---------------- | -------------- | ------ |
| MK-001 | AES-256 | 2025-01-15 | 2026-01-15 | KEK Generation | Activa |
| MK-002 | RSA-4096 | 2025-01-15 | 2026-01-15 | Cert Signing | Activa |

### Claves de Datos de Pacientes

| ID | Algoritmo | Propósito | Rotación | Datos Afectados | Estado |
| ------ | ----------- | --------------------- | ---------- | --------------- | ------ |
| PD-001 | AES-256-GCM | Historiales clínicos | 2025-09-29 | ~50K registros | Activa |
| PD-002 | AES-256-GCM | Imágenes diagnósticas | 2025-10-15 | ~200K imágenes | Activa |

### Claves de Modelos IA

| ID | Algoritmo | Modelo | Versión | Próxima Rotación | Estado |
| ------ | ---------- | -------------------- | ------- | ---------------- | ------ |
| AI-001 | ECDSA-P384 | Modelo Dermatológico | v2.1.5 | 2026-08-29 | Activa |
| AI-002 | ECDSA-P384 | Modelo Melanoma | v1.8.2 | 2026-08-29 | Activa |

8.2 Métricas de seguridad​

MétricaObjetivoActualEstado
Claves rotadas a tiempo100%98%⚠️
Certificados expirados00✅
Accesos no autorizados00✅
Tiempo generación claves<5s3.2s✅
Disponibilidad HSM99.99%99.95%✅
Claves sin uso >90 días<5%8%⚠️

Respuesta a incidentes​

9.1 Compromiso de claves​

Procedimiento de respuesta inmediata:

def respond_to_key_compromise(compromised_key_id):
# 1. Revocación inmediata
revoke_key_immediately(compromised_key_id)

# 2. Notificación
alert_security_team("KEY_COMPROMISE", compromised_key_id)

# 3. Evaluación de impacto
affected_data = assess_impact(compromised_key_id)

# 4. Rotación de emergencia
new_key = emergency_key_rotation(compromised_key_id)

# 5. Re-cifrado de datos afectados
reencrypt_affected_data(affected_data, new_key)

# 6. Investigación forense
forensic_analysis = investigate_compromise(
key_id=compromised_key_id,
timeframe=last_7_days,
scope=['access_logs', 'network_traffic', 'system_logs']
)

# 7. Notificaciones regulatorias si necesario
if affects_personal_data(affected_data):
notify_dpa_within_72_hours()

if affects_medical_device(affected_data):
notify_competent_authority()

# 8. Documentación
create_incident_report({
'key_id': compromised_key_id,
'detection_time': datetime.utcnow(),
'impact': affected_data,
'response': new_key,
'forensics': forensic_analysis
})

Procedimientos operativos​

10.1 Backup de claves​

Backup Strategy:
Frequency: Daily incremental, Weekly full

Methods:
Primary: HSM cluster replication
Secondary: Encrypted export to cold storage
Tertiary: Paper backup (QR codes) in safe

Verification:
- Monthly restore test
- Quarterly full recovery drill
- Annual third-party audit

Storage_Locations:
- Online: Multi-region cloud
- Nearline: Local datacenter vault
- Offline: Bank safety deposit box

10.1bis Procedimientos de Recuperación de Claves​

Procedimiento de escrow y recuperación según ENS:

class ENSKeyEscrowRecovery:
"""
Gestión de escrow y recuperación de claves según ENS
"""

def __init__(self):
self.escrow_threshold = 3 # Mínimo de 3 custodios para recuperación
self.authorized_custodians = self.load_authorized_custodians()

def create_key_escrow(self, key_id: str, criticality: str) -> dict:
"""
Crear escrow de clave usando Shamir's Secret Sharing
"""

if criticality not in ['critical', 'essential', 'important']:
raise ValueError("Invalid criticality level")

# Solo claves críticas y esenciales van a escrow
if criticality not in ['critical', 'essential']:
return {'escrow_required': False}

# Obtener clave del HSM
key_material = self.export_key_from_hsm(key_id)

# Configurar Shamir según criticidad
if criticality == 'critical':
threshold = 5 # Requiere 5 de 7 fragmentos
total_shares = 7
else: # essential
threshold = 3 # Requiere 3 de 5 fragmentos
total_shares = 5

# Generar fragmentos
shares = self.generate_shamir_shares(
key_material,
threshold,
total_shares
)

# Distribuir fragmentos a custodios
escrow_records = []
for i, share in enumerate(shares):
custodian = self.select_custodian_for_share(i, criticality)

# Cifrar fragmento con clave del custodio
encrypted_share = self.encrypt_share_for_custodian(share, custodian)

# Almacenar en ubicación segura
storage_location = self.store_encrypted_share(
encrypted_share,
custodian,
key_id
)

escrow_records.append({
'share_number': i + 1,
'custodian': custodian['name'],
'storage_location': storage_location,
'creation_date': datetime.now().isoformat(),
'verification_hash': self.calculate_share_hash(encrypted_share)
})

# Crear registro de escrow
escrow_record = {
'key_id': key_id,
'escrow_id': f"ESC-{key_id}-{int(time.time())}",
'criticality': criticality,
'threshold': threshold,
'total_shares': total_shares,
'shares': escrow_records,
'legal_authority': self.get_legal_authority_for_escrow(key_id),
'retention_period': '7_years',
'compliance_frameworks': ['ENS', 'MDR']
}

# Registrar en inventario de escrow
self.register_escrow_record(escrow_record)

# Generar certificado de escrow
self.generate_escrow_certificate(escrow_record)

return escrow_record

def recover_key_from_escrow(self, escrow_id: str,
authorization: dict) -> dict:
"""
Recuperar clave desde escrow con autorización múltiple
"""

# Validar autorización
if not self.validate_recovery_authorization(authorization):
raise SecurityException("Insufficient authorization for key recovery")

escrow_record = self.get_escrow_record(escrow_id)

# Recopilar fragmentos necesarios
required_shares = escrow_record['threshold']
available_custodians = self.get_available_custodians(escrow_record)

if len(available_custodians) < required_shares:
raise RecoveryException("Insufficient custodians available")

# Solicitar fragmentos a custodios
recovered_shares = []
for custodian in available_custodians[:required_shares]:
share = self.request_share_from_custodian(
custodian,
escrow_id,
authorization
)

# Verificar integridad del fragmento
if self.verify_share_integrity(share, custodian):
recovered_shares.append(share)
else:
raise IntegrityException(f"Share from {custodian} failed integrity check")

# Reconstruir clave usando Shamir
if len(recovered_shares) >= required_shares:
reconstructed_key = self.reconstruct_key_from_shares(recovered_shares)

# Importar clave a HSM
new_key_id = self.import_key_to_hsm(reconstructed_key)

# Registrar recuperación
self.log_key_recovery({
'original_key_id': escrow_record['key_id'],
'new_key_id': new_key_id,
'escrow_id': escrow_id,
'recovery_date': datetime.now().isoformat(),
'authorized_by': authorization['authorized_by'],
'custodians_involved': [c['name'] for c in available_custodians[:required_shares]],
'legal_basis': authorization.get('legal_basis', 'operational_recovery')
})

return {
'status': 'success',
'new_key_id': new_key_id,
'recovery_timestamp': datetime.now().isoformat()
}
else:
raise RecoveryException("Unable to recover sufficient shares")

10.2 Recuperación de desastres​

Plan de recuperación de claves:

  1. Activar HSM de respaldo
  2. Restaurar master keys desde quórum
  3. Re-generar claves operacionales
  4. Verificar integridad de datos
  5. Restablecer servicios por prioridad
  6. Auditoría post-recuperación

Formación y concienciación​

Programa de formación:

  • Básico (todos): Importancia de protección de claves
  • Intermedio (IT): Uso seguro de claves y certificados
  • Avanzado (Security): Gestión de HSM y PKI
  • Especializado (Key Custodians): Procedimientos de escrow y recuperación

Integración con otros controles ENS​

  • MP.SW.2: Claves para firma de código
  • MP.COM: Certificados TLS/SSL
  • MP.SI.2: Cifrado de soportes
  • OP.ACC.5: Claves de autenticación fuerte
  • OP.EXP.10: Firma de logs de auditoría

Documentación y registros​

  • T-024-018: Procedimiento completo de gestión
  • T-024-019: Política de uso aprobada
  • T-024-020: Inventario actualizado de claves
  • R-110-003: Inventario de claves criptográficas ENS
  • Registros de auditoría: Todos los eventos de claves
  • Certificados de destrucción: Archivo permanente
  • Informes de rotación: Evidencia de cumplimiento
  • Certificados de escrow: Documentación legal de custodia
  • Registros de recuperación: Evidencia de accesos a escrow
  • Informes de cumplimiento CCN-STIC-807: Evaluaciones periódicas

Referencias cruzadas ENS e integración​

14.1 Integración con otros controles ENS​

Control ENSRelaciónDescripción de integración
OP.EXP.7Gestión de incidentesRespuesta a compromiso de claves
OP.EXP.10Registros de actividadFirma criptográfica de logs
OP.ACC.5AutenticaciónClaves para MFA y certificados
MP.COM.2Protección comunicacionesCertificados TLS/SSL
MP.SW.2Aceptación aplicacionesFirma digital de código
MP.SI.2Eliminación de soportesClaves de cifrado de medios
OP.CONT.2Plan de continuidadBackup y recuperación de claves

14.2 Referencias a documentación ENS​

  • T-110-007: Matriz RACI - Roles en gestión de claves
  • T-110-008: CCN-CERT - Notificación de incidentes criptográficos
  • ORG.1: Política de seguridad - Marco para políticas de claves
  • OP.PL.1: Análisis de riesgos - Riesgos criptográficos
  • OP.PL.2: Arquitectura de seguridad - Integración de HSM

14.3 Cumplimiento regulatorio médico​

Medical_Compliance_Integration:
MDR_2017_745:
article_17: "Sistemas de gestión de calidad"
annex_I_17_2: "Medidas de seguridad IT"
implementation: "Claves para protección de datos clínicos"

IEC_62304:
section_5_5: "Integración e integración testing"
section_7: "Procesos de gestión de riesgos del software"
application: "Claves para firma de software médico"

ISO_14971:
clause_4_3: "Gestión de riesgos de dispositivos médicos"
clause_7: "Evaluación y control de riesgos"
integration: "Riesgos criptográficos en análisis general"

FDA_Cybersecurity_Guidance:
premarket: "Documentación de controles criptográficos"
postmarket: "Gestión de vulnerabilidades en algoritmos"
application: "Validación de implementación criptográfica"

Métricas de efectividad ENS​

15.1 KPIs específicos de cumplimiento ENS​

class ENSCryptographicMetrics:
"""
Métricas específicas de cumplimiento ENS para OP.EXP.11
"""

def calculate_ens_compliance_score(self) -> dict:
"""
Calcula puntuación de cumplimiento ENS
"""

metrics = {
'algorithm_compliance': self.check_algorithm_compliance(),
'key_length_compliance': self.check_key_length_compliance(),
'rotation_compliance': self.check_rotation_compliance(),
'hsm_usage_compliance': self.check_hsm_usage_compliance(),
'backup_compliance': self.check_backup_compliance(),
'audit_compliance': self.check_audit_compliance()
}

# Calcular puntuación ponderada
weights = {
'algorithm_compliance': 0.25,
'key_length_compliance': 0.20,
'rotation_compliance': 0.20,
'hsm_usage_compliance': 0.15,
'backup_compliance': 0.10,
'audit_compliance': 0.10
}

total_score = sum(metrics[key] * weights[key] for key in weights)

return {
'overall_score': total_score,
'individual_metrics': metrics,
'compliance_level': self.determine_compliance_level(total_score),
'areas_for_improvement': self.identify_improvement_areas(metrics)
}

15.2 Métricas operacionales​

Métrica ENSObjetivoMediciónResponsable
Cumplimiento CCN-STIC-807100%MensualKey Administrator
Rotación de claves en plazo>98%AutomáticaSystem
Disponibilidad HSM>99.9%ContinuaInfrastructure Team
Tiempo de recuperación de escrow<4 horasPor eventoSecurity Team
Auditorías de claves completadas100%TrimestralCompliance Team
Certificados próximos a vencer0DiariaCertificate Manager
Incidentes criptográficos0Por eventoCISO

Signature meaning

The signatures for the approval process of this document can be found in the verified commits at the repository for the QMS. As a reference, the team members who are expected to participate in this document and their roles in the approval process, as defined in Annex I Responsibility Matrix of the GP-001, are:

  • Author: Team members involved
  • Reviewer: JD-003, JD-004
  • Approver: JD-001
Previous
OP.EXP.10 Protección de los registros de actividad
Next
OP.EXP.2 Configuración de seguridad
  • Documentos de referencia
    • Referencias normativas ENS
    • Documentación interna Legit Health
    • Referencias internacionales
    • Referencias médicas
  • Guía de implantación
    • Objetivo
    • Alcance
    • Arquitectura de gestión de claves
      • 3.1 Componentes del sistema
      • 3.2 Jerarquía de claves
    • Ciclo de vida de las claves
      • 4.1 Generación de claves
      • 4.2 Distribución segura
      • 4.3 Almacenamiento seguro
      • 4.4 Uso de claves
      • 4.5 Rotación de claves
      • 4.6 Destrucción de claves
    • Controles de seguridad específicos
      • 5.1 Segregación de funciones
      • 5.1bis Directrices de Uso de HSM según CCN-STIC-807
      • 5.2 Control de acceso dual
      • 5.3 Escrow de claves
    • Protección física de material criptográfico
      • 6.1 HSM físico
      • 6.2 Transporte de material criptográfico
    • Gestión de certificados digitales
      • 7.1 Infraestructura PKI
      • 7.2 Ciclo de vida de certificados
    • Auditoría y cumplimiento
      • 8.1 Registros de auditoría
      • 8.1bis Inventario Completo de Claves Criptográficas
      • 8.2 Métricas de seguridad
    • Respuesta a incidentes
      • 9.1 Compromiso de claves
    • Procedimientos operativos
      • 10.1 Backup de claves
      • 10.1bis Procedimientos de Recuperación de Claves
      • 10.2 Recuperación de desastres
    • Formación y concienciación
    • Integración con otros controles ENS
    • Documentación y registros
    • Referencias cruzadas ENS e integración
      • 14.1 Integración con otros controles ENS
      • 14.2 Referencias a documentación ENS
      • 14.3 Cumplimiento regulatorio médico
    • Métricas de efectividad ENS
      • 15.1 KPIs específicos de cumplimiento ENS
      • 15.2 Métricas operacionales
All the information contained in this QMS is confidential. The recipient agrees not to transmit or reproduce the information, neither by himself nor by third parties, through whichever means, without obtaining the prior written permission of Legit.Health (AI LABS GROUP S.L.)