Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
Claims Reference

Encryption Key Claim


The Encryption Key Claim allows an application to request a secret key derived from the user's wallet master key. This process uses a provided salt to generate a unique, deterministic key, enabling applications to encrypt user-specific data that only the user can decrypt. This method enhances security by ensuring sensitive data remains inaccessible without the user's direct involvement, as the application never handles the user's master key.

How It Works#

When an application requests an encryptionKey, the wallet performs a cryptographic derivation. It combines the user's secret key with the salt provided by the application and hashes the result (typically using SHA3) to produce a secure encryption key. This process is deterministic, meaning the same secret key and salt will always produce the same encryption key.

Here is a simplified flow of the interaction:


Parameters#

The encryptionKey claim object consists of the following fields:

Parameter

Type

Description

type

string

Required. Must be 'encryptionKey'.

description

string

A user-friendly message displayed in the wallet, explaining why the application needs the encryption key. Defaults to 'Please provide encryptionKey to continue.'.

salt

string

Required. A unique string provided by the application to be used in the key derivation process. This ensures that the generated key is specific to this context. A common practice is to use a unique identifier like an application-specific user DID.

delegation

string

Optional. A JWT that proves the application has the authority to request this key on behalf of another party. See the Delegated Connect guide for more details.

Example Request#

Here is how an application can request an encryption key. In this example, the application needs to decrypt some user-specific information. It provides a salt (the application's DID) and a delegation token to authorize the action.

// From a DID Connect handler file

const assert = require('assert');
const { User } = require('../../models');

module.exports = {
action: 'decrypt-info',
claims: {
encryptionKey: async ({ extraParams: { sessionDid } }) => {
const user = await User.ensureOne({ did: sessionDid });
const [app] = user.generatedApps;

// Ensure the user has an application account and has signed a delegation
assert(app, 'You must generate an application account first');
assert(app.delegation, 'You must sign delegation before retrieve encryption key');

return {
type: 'encryptionKey',
description: 'Please provide the key to decrypt your information.',
salt: app.address, // Using the app's DID as the salt
delegation: app.delegation,
};
},
},
// ... onAuth handler
};

This configuration dynamically generates the claim, ensuring that a valid user session and delegation exist before requesting the key.

Handling the Wallet Response#

Once the user approves the request in their wallet, the derived key is sent back to the onAuth callback. The application can then use this key to perform cryptographic operations, such as decrypting a message.

// From the same DID Connect handler file

const AES = require('@ocap/mcrypto/lib/crypter/aes').default;
const { fromBase58 } = require('@ocap/util');
const assert = require('assert');
const { User } = require('../../models');

module.exports = {
// ... claims definition
onAuth: async ({ claims, extraParams: { sessionDid } }) => {
const user = await User.ensureOne({ did: sessionDid });
const [app] = user.generatedApps;

// Find the encryptionKey claim in the wallet's response
const claim = claims.find(x => x.type === 'encryptionKey');
const password = fromBase58(claim.key); // The derived key is the 'password'

// Use the key to decrypt data
const decrypted = AES.decrypt(app.encrypted, password, 'buffer').toString('utf8');
assert(decrypted === 'playground', 'Failed to decrypt');

return {
successMessage: 'Your provided encryption key is correct, and the data was successfully decrypted!',
};
},
};

In this onAuth handler, the code finds the encryptionKey claim, decodes the key from base58, and uses it with an AES decryption function to access the protected data. This completes the secure workflow without ever exposing the user's primary secret key.