Saltar al contenido principal

Gestión de claves de un DID

Una vez registrado el DID inicial, la entidad puede gestionar el ciclo de vida de su material criptográfico a través de la DID Registry API:

  • Añadir nuevas claves (addVerificationMethod).
  • Asociar usos a esas claves (addVerificationRelationship).
  • Expirar o revocar claves comprometidas (expireVerificationMethod, revokeVerificationMethod).
  • Rotar una clave por otra (rollVerificationMethod).
  • Añadir o revocar controladores (addController, revokeController).
Patrón común

Todas las operaciones siguen el mismo patrón de 3 pasos: crear transacción → firmar off-chain → enviar. Si no estás familiarizado con el flujo, lee primero Onboarding del DID.

Añadir una clave P-256 para emitir credenciales

Para poder emitir credenciales verificables, una entidad necesita una clave P-256 registrada como assertionMethod. El flujo completo es:

  1. Generar la clave P-256.
  2. Registrar el verification method.
  3. Asociarlo a la relación assertionMethod.

1. Generar clave P-256

Desde isbe-identity-did-gen:

./did-gen keys -c P-256

Salida (resumida):

Private Key (JWK):
{
"kty": "EC",
"crv": "P-256",
"alg": "ES256",
"x": "<X>",
"y": "<Y>",
"d": "<D>"
}

Public Key (JWK):
{
"kty": "EC",
"crv": "P-256",
"alg": "ES256",
"x": "<X>",
"y": "<Y>"
}

Public Key (JWK) Thumbprint:
WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4

Public Key (hex of JWK):
0x7b226b7479223a224543222c22637276223a22502d323536222c...

Guarda el JWK privado, el thumbprint y la hex JWK pública.

2. Registrar el verification method

Llama a POST /api/v1/contract/addVerificationMethod con:

{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"publicKeyType": "JsonWebKey2020",
"publicKey": "0x7b226b7479223a224543222c22637276223a22502d323536222c...",
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

Notas:

  • vMethodId — Usa el thumbprint JWK de la clave pública. Recomendado por ser deterministico y trazable.
  • publicKeyType — Para claves envueltas en JWK (P-256, o también secp256k1 si quieres registrarlo con metadata JWK completa) usa JsonWebKey2020. La curva real la determina el crv que pongas dentro del JWK serializado. Si registras una secp256k1 sin envoltura (64 bytes XY hex puros), usa publicKeyType: "secp256k1". El literal "P-256" aparece en la spec pero la API lo rechaza con 400 UNSUPPORTED; para P-256 usa siempre JsonWebKey2020 con crv: "P-256".
  • publicKey — La hex JWK pública (NO la hex pública en formato uncompressed; ese formato solo se usa con publicKeyType: "secp256k1").
  • from — Sigue siendo la EOA de tu clave secp256k1 de control, NO la EOA derivada de la clave P-256.

Firma la respuesta off-chain (ethers.js, eth_account o cualquier librería EVM equivalente) y envíala mediante POST /api/v1/transactions/send. Tienes los snippets completos en Registro desde la API — paso 4.

3. Asociar la relación de verificación

El material criptográfico ya está registrado, pero no será utilizable hasta que se le asigne una relación. Llama a POST /api/v1/contract/addVerificationRelationship:

{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"name": "assertionMethod",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"notBefore": 1774603242,
"notAfter": 2090222442,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

Valores válidos para name:

nameUso
assertionMethodFirmar credenciales y acreditaciones.
authenticationAutenticarse como el DID.
keyAgreementAcuerdo de claves para cifrado.
capabilityInvocationInvocar capacidades delegadas.
capabilityDelegationDelegar capacidades.

Firma y envía la transacción. Tras confirmación, la clave queda lista para uso operativo y aparecerá en el DID Document bajo la sección correspondiente.

Revocar una clave

Cuando una clave deja de ser segura (compromiso, rotación, etc.) debe revocarse para evitar que se acepten firmas hechas con ella.

POST /api/v1/contract/revokeVerificationMethod
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"notAfter": 1774700000,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}
  • notAfter indica el timestamp a partir del cual la clave deja de ser válida. Para revocación inmediata, usa el timestamp actual.
  • Las credenciales firmadas con esta clave antes de notAfter siguen siendo válidas; las posteriores no.

Expirar una clave

Similar a la revocación, pero se usa cuando la clave llega al final natural de su vida útil (la fecha planificada notAfter). Conceptualmente equivalente, pero semánticamente distinto: la revocación implica compromiso, la expiración no.

POST /api/v1/contract/expireVerificationMethod
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "WqpsDjTHnYVNvX8qx4a1FER8NgnEBS6DjLbDVrX-Fg4",
"notAfter": 2090221463,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

Rotar una clave

La rotación combina el alta de una clave nueva y la baja diferida de la antigua. Es útil para renovar claves sin perder operatividad.

POST /api/v1/contract/rollVerificationMethod
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"vMethodId": "<NUEVO_THUMBPRINT>",
"publicKeyType": "JsonWebKey2020",
"publicKey": "0x<NUEVA_HEX_JWK>",
"notBefore": 1774700000,
"notAfter": 2090300000,
"oldVMethodId": "<THUMBPRINT_ANTERIOR>",
"duration": 86400,
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}
  • duration (en segundos) define el periodo de solape durante el cual ambas claves son válidas. Permite migrar firmantes con tiempo.
  • Pasado ese periodo, la clave antigua queda expirada automáticamente.

Añadir o revocar controladores

Un controlador es una cuenta autorizada a modificar el DID Document. Útil para delegar la administración en otra entidad o en una EOA distinta.

Añadir

POST /api/v1/contract/addController
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"controller": "0x<NUEVA_EOA>",
"from": "0x<EOA_ACTUAL>"
}

Revocar

POST /api/v1/contract/revokeController
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"controller": "0x<EOA_A_REVOCAR>",
"from": "0x<EOA_ACTUAL>"
}
No dejes el DID sin controlador

Antes de revocar el último controlador, asegúrate de tener al menos otro registrado. Si no, perderás el control del DID de forma irreversible.

Actualizar metadatos

Cambiar alsoKnownAs

POST /api/v1/contract/updateAlsoKnownAs
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"alsoKnownAs": "urn:oid:organizationIdentifier:NUEVO_CODIGO",
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

Cambiar baseDocument (contexto JSON-LD)

POST /api/v1/contract/updateBaseDocument
{
"did": "did:isbe:uc:z12kVar5p6bD5WCjEJcQ18Zyt8XV",
"baseDocument": "{\"@context\":[\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/suites/jws-2020/v1\"]}",
"from": "0xAe0E493C67f75381b0954644836A3C16c79D0dFD"
}

Sustituir el DID Document completo

Si necesitas reemplazar el DID Document de raíz (por ejemplo, tras una rotación de la clave de control secp256k1), usa:

POST /api/v1/contract/insertDidDocument

El cuerpo es idéntico al de insertFirstDidDocument salvo que el DID ya existe y la operación está sujeta a verificación de controlador previo en lugar de a la autorización inicial.

Diferencia clave entre los dos endpoints
  • insertFirstDidDocument — Solo para el alta inicial de un DID nunca antes registrado. Requiere autorización especial.
  • insertDidDocument — Para reescribir el documento de una entidad que ya existe en el registro. Solo el controlador actual puede invocarlo.