mintBlue
GuidesTransactions

Encrypt and sign an output

Turn on client-side encryption and a digital signature for a data or file output, and check from both sides what each flag changed.

Two boolean flags decide how much of a record is readable by anyone who fetches it, and whether a reader can tell who wrote it. Both default to off, so an output submitted without them is published in the clear and unsigned.

They apply to the two general-purpose output types, data and file. The named envelope formats carry their own encryption and signing arguments, documented per format under Envelope formats.

What each flag does

FlagWhat it changes
encrypt: trueThe value is encrypted on your machine, with your own key, before the transaction is submitted. What is published is the encrypted content.
sign: trueA digital signature is made over the value with your own key and travels with the record, so a reader can check who wrote it without asking mintBlue.

The two are independent. Signing without encrypting is a public statement that is attributable. Encrypting without signing is a private value with no author attached. Most integrations want both.

Turn them on

const outputs = [
  {
    type: 'data',
    value: {
      name: 'John Doe',
      email: 'john@doe.com',
      order: 'order#1234',
    },
    sign: true,
    encrypt: true,
  },
];

const { txid } = await client.createTransaction({
  project_id: process.env.MINTBLUE_PROJECT_ID,
  outputs,
});

Check it worked

There are two checks, and they answer different questions.

Can you still read it? Fetch the transaction with parse: true. The client decrypts locally, with the keys Mintblue.create unwrapped into memory, so the value comes back the way you submitted it.

const transaction = await client.getTransaction({ txid, parse: true });

const record = transaction.outputs.find((output) => output.type === 'data');
console.log(record.value);

Is it actually encrypted? Fetch the same transaction with parse: false and look at the raw transaction instead. Nothing decrypts it, so the value is not there to be read.

const raw = await client.getTransaction({ txid, parse: false });
console.log(raw.rawtx.includes(Buffer.from('john@doe.com').toString('hex')));

If that prints false, the plaintext is not sitting in what was published, which is what encrypt: true is for. The same transaction opened in the console shows the value in the clear, because the console holds your keys too.

Where the keys come from, and what that costs

The keys used for both operations are yours. They are unwrapped in your process when Mintblue.create runs, which is why the SDK can decrypt your own records without a secret being passed into each call.

That has a consequence worth being explicit about. An SDK access token carries the secret that unwraps your master key for local use, so anyone holding that token can decrypt everything the account can decrypt. Treat it as the key itself, not as a password to a service. Non-custodial keys sets out what is held where, per deployment model, and SDK covers the difference between the SDK token and the API token.

Next

On this page