Skip to content
/ iron Public
forked from hapijs/iron

Encapsulated tokens (encrypted and mac'ed objects)

License

Notifications You must be signed in to change notification settings

eladams/iron

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iron

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 tempered with, and also provides a simple mechanism for password rotation.

Current version: 0.2.0

Build Status

Table of Content

- [Usage](#usage) - [Options](#options)

- [**Security Considerations**](#security-considerations) - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)

- [**Frequently Asked Questions**](#frequently-asked-questions)

- [**Acknowledgements**](#acknowledgements)

Introduction

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
  • 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

Usage

To seal an object:

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

var password = 'some_not_random_password';

Iron.seal(obj, password, Iron.defaults, function (err, sealed) {

    console.log(sealed);
});

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:

Iron.unseal(sealed, password, Iron.defaults, function (err, unsealed) {

    // unsealed has the same content as obj
});

Options

iron provides a few options for customizing the key deriviation algorithm used to generate encryption and integrity verification keys as well as the algorithms and salt sizes used. The 'seal()' and 'unseal()' methods take an options object with the following required keys:

  • encryption - defines the options used by the encryption process.
  • integrity - defines the options used by the HMAC itegrity verification process.

Each of these option objects includes the following required keys:

  • saltBits - the size of the salt (random buffer used to ensure that two identical objects will generate a different encrypted result.
  • algorithm - the algorithm used ('aes-256-cbc' for encryption and 'sha256' for integrity are the only two supported at this time).
  • iterations - the number of iterations used to derive a key from the password (set to '1' if not sure).

iron includes a default options object which can be passed to the methods as shown above in the example. The default settings are:

var options = {
    encryption: {
        saltBits: 256,
        algorithm: 'aes-256-cbc',
        iterations: 1
    },
    integrity: {
        saltBits: 256,
        algorithm: 'sha256',
        iterations: 1
    }
};

Alternatively, a Buffer object of sufficient size (matching the algorithm key size requirement) can be passed as the password, in which case, saltBits and iterations are ignored and the buffer is used as-is.

Security Considerations

The greatest sources of security risks are usually found not in iron but in the policies and procedures surrounding its use. Implementers are strongly encouraged to assess how this module addresses their security requirements. This section includes an incomplete list of security considerations that must be reviewed and understood before using iron.

Plaintext Storage of Credentials

The iron password is only used to derive keys and is never sent or shared. However, in order to generate (and regenerate) the keys used to encrypt the object and compute the request MAC, the server must have access to the password in plaintext form. This is in contrast, for example, to modern operating systems, which store only a one-way hash of user credentials.

If an attacker were to gain access to the password - or worse, to the server's database of all such password - he or she would be able to encrypt and decrypt any sealed object. Accordingly, it is critical that servers protect these passwords from unauthorized access.

Frequently Asked Questions

Where is the protocol specification?

If you are looking for some prose explaining how all this works, there isn't any. iron is being developed as an open source project instead of a standard. In other words, the code is the specification. Not sure about something? Open an issue!

Is it done?

No but it's close. Until this module reaches version 1.0.0 it is considered experimental and is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions and suggestions.

How come the defaults must be manually passed and not automatically applied?

Because you should know what you are doing and explicitly set it. The options matter a lot to the security properties of the implementation. While reasonable defaults are provided, you still need to explicitly state you want to use them.

Acknowledgements

Special thanks to Adam Barth for his infinite patiace, and always insightful feedback and advice.

The iron logo was based on origin artwork created by Chris Carrasco.

About

Encapsulated tokens (encrypted and mac'ed objects)

Resources

License

Stars

Watchers

Forks

Packages

No packages published