Encapsulated tokens (encrypted and mac'ed objects).

Latest Version: 6.0.0

npm: npm install @hapi/iron

yarn: yarn add @hapi/iron

Module Status:
Version License Node Dependencies CI
hapi helmet github logo
BSD 12, 14 Dependency Status Build Status


iron is a cryptographic utility for sealing a JSON object using symmetric key encryption with message
integrity verification. Or in other words, it lets you encrypt an object, send it around (in
cookies, authentication credentials, etc.), then receive it back and decrypt it. The algorithm
ensures that the message was not tampered with, and also provides a simple mechanism for password

Note: the wire protocol has not changed since 1.x (the version increments reflected a change in
the internal error format used by the module and by the node API as well as other node API changes).

iron provides methods for encrypting an object, generating a message authentication code (MAC),
and serializing both into a cookie / URI / HTTP header friendly format. Sealed objects are useful
in cases where state has to reside on other applications not under your control, without exposing
the details of this state to those application.

For example, sealed objects allow you to encrypt the permissions granted to the authenticated user,
store those permissions using a cookie, without worrying about someone modifying (or even knowing)
what those permissions are. Any modification to the encrypted data will invalidate its integrity.

The seal process follows these general steps:

  • generate encryption salt saltE
  • derive an encryption key keyE using saltE and a password
  • generate an integrity salt saltI
  • derive an integrity (HMAC) key keyI using saltI and the password
  • generate a random initialization vector iv
  • encrypt the serialized object string using keyE and iv
  • mac the encrypted object along with saltE and iv
  • concatenate saltE, saltI, iv, and the encrypted object into a URI-friendly string


To seal an object:

const obj = {
    a: 1,
    b: 2,
    c: [3, 4, 5],
    d: {
        e: 'f'

const password = 'some_not_random_password_that_is_at_least_32_characters';

try {
    const sealed = await Iron.seal(obj, password, Iron.defaults);
} catch (err) {

The result sealed object is a string which can be sent via cookies, URI query parameter, or an HTTP header attribute. To unseal the string:

try {
    const unsealed = await Iron.unseal(sealed, password, Iron.defaults);
} catch (err) {