GithubHelp home page GithubHelp logo

iron's Introduction

@hapi/iron

Encapsulated tokens (encrypted and mac'ed objects).

iron is part of the hapi ecosystem and was designed to work seamlessly with the hapi web framework and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out hapi โ€“ they work even better together.

Visit the hapi.dev Developer Portal for tutorials, documentation, and support

Useful resources

iron's People

Contributors

cjihrig avatar d2lam avatar devinivy avatar dminkovsky avatar dvirsh avatar ecki avatar geek avatar hueniverse avatar hugowetterberg avatar jarrodyellets avatar lloydbenson avatar lukasolson avatar marsup avatar mtharrison avatar nargonath avatar newswim avatar nfcampos avatar nwhitmont avatar simenbrekken avatar stevebest avatar tinchoz49 avatar tomsteele avatar vvo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iron's Issues

Support variable iterations

It would be good to have the iterations count become apart of the returned string on seal. Then unseal would be able to take it and apply the needed iterations. This way you could gradually increase the iterations to keep up hardware.

Thoughts?

iron / crypto

iron original line missing digest argument?

Crypto.pbkdf2(password, salt, options.iterations, algorithm.keyBits / 8, (err, derivedKey) => {

Changed to this to make it work:

Crypto.pbkdf2(password, salt, options.iterations, algorithm.keyBits / 8, 'sha512',(err, derivedKey) => {

Please confirm if this is not correct. Thanks

Another PHP Port

I have completed a PHP port of Iron.

This Hawk port was designed to be used by the Oz PHP port (currently in beta). However, it can be used as a standalone package if you only need Iron.

I also focused on making the API simple and similar to the original JavaScript Iron API. So, if you are familiar with the JavaScript version of Iron, you should not have a problem using this PHP port of Iron.

If you find any bugs or have questions, open an issue on the Github repository for this PHP port.

Side Note: I also created a PHP port of Hawk.

Iron.seal is not working

I was using this method and the callback was returning me the sealed value but after upgrading the version it stopped working.

Iron.seal(data, sealPass, Iron.defaults, (err, sealed) => {
    if (err) {
      console.log(err);
    }
    console.log(sealed);
  }); 

Generate encryption key and integrity key in one step

99% of users are probably going to use a single password for encryption and integrity. We could use pbkdf2 to generate two keys at once and split it in half. Increasing performance by removing additional calls without decreasing security. Using one salt for both keys is perfectly fine.

We could also set the IV counter to 0. Since the key is never the same, and a random IV is no different as far as cipher strength. But I understand objections to this.

Performance impact of higher iteration count

The new iteration default makes generating per-encryption key very expensive. The way iron is used to encrypt cookies, this will add significant cost to each request. In practice, there is little value from generating a unique encryption key per request, and it is probably enough to reuse the same one across requests.

Need to add a new API to support this common use case. It is already possible today by passing in a Buffer key but need a higher level API to make it easy with some kind of internal caching of keys. The module already keeps the master password in memory, so this will not change the security properties.

Support for configuring replacer and reviver functions

I could really use a replacer function that would be used in the JSON.stringify call when the object is sealed; and vice versa a revivir function for when the object is unsealed.
This to transform some objects in a Hapi cookie.

synchronous seal

I'm testing endpoints and would like to be able to seal objects synchronously so I do not have to wrap a test in a callback.

I believe the functionality is possible with jwt and bcrypt.

I wonder if this has been requested before or maybe there is a good reason that it doesn't exist already.

Option localtimeOffsetMsec should be removed

localtimeOffsetMsec unnecessarily skews the calculation of the TTL of the token. All installations of iron have to have the same localtimeOffsetMsec or the TTL of the token will be miscalculated. Configuring localtimeOffsetMsec to the correct timezone offset cause tokens to expire at the wrong times when sealers and unsealers are sitting in different timezones.

For example, if you have a sealer configured in eastern time and an unsealer configured in pacific time.
example ttl = 1hour
The sealer is on eastern time so the localtimeOffsetMsec : -4 hours
The unsealer is on pacific time so its localtimeOffsetMsec : -7 hours

Now say the current time is 12:00 GMT
The sealer creates a new token with expiry time to be 12 - 4 + 1 hours = 09:00 GMT
Say the expired token arrives the unsealer 2 hours later (14:00 GMT).
The unsealer will calculate its current time to be 14 -7 hours = 07:00 GMT
The unsealer will then calculate the the expiry time of the token to be 09:00 > 07:00 and so believes it is not expired.
To this unsealer, tokens generated by the sealer have an additional 3 hour grace period over the configured TTL.

The timezone offset math should be removed and all timestamps embedded in the token and calculations for expiry be based on GMT, which is the default returned by Date.now().

Add expiration

Support including an optional expiration time somewhere in the iron blob and validate it when unsealing.

Encrypting regular String

I was planning to use iron to encrypt/decrypt regular String values (not JSON), and since there is no explicit mention of it in the docs or an explicit test for it, I was wondering if there is any caveat or security implication of doing it?

Communicating selected options

seal() and unseal() require the use of the same options for successful unsealing.

Have you thought about a situation, where token 'sealer' is not the same system as the token 'unsealer'? For example, when an authorization server creates a ticket to be used by resource servers for authentication and authorization).

Would it make sense to append the options to the token for the 'unsealer' to know. Or would you rather prefer to declare that issue out of scope and defer to out of band agreement between 'sealer' and 'unsealer'?

Should passwordId be hex- or base64url-encoded?

All the parts of the sealed token make sure that they only contain URL-(etc.) safe characters. Except for the passwordId, which is AFAIU put into the token as-is.

Wouldn't it make sense to hex- or base64url-encode the passwordId as well, to ensure that the overall string is URL-(etc.) safe?

Or else, to constrain the passwordId to only contain URL-(etc.) safe characters - which would be simpler and the common case anyway, IMHO.

Why not use AES-256-GCM

I'm just curious, as I'm investigating the possibility of using this library, or at least this idea. Why not just use AES-256-GCM instead of using two separate keys and two separate functions?

Exposing PBKDF2 hashing algorithm for key generation, or just upgrading it

I was glancing through Iron and I noticed that there was a slight mismatch between the minimum password length and the key derivation method, namely the SHA-1 hashing algorithm used inside PBKDF2.

This post explains it pretty concisely I think (https://www.chosenplaintext.ca/2015/10/08/pbkdf2-design-flaw.html).

The TL:DR is that by using a password longer than the 20 bytes that SHA-1 outputs, pbkdf2 is doing twice the amount of iterations for little, if no benefit.

All I am proposing is to change the digest option used in pbkdf2 in the generateKey() function to sha256 at least, to use all 32 bytes meaningfully.

I realize this would break existing implementations, so exposing it as an option would also be fine. I'm willing to write a pull request to do so, just wanted to put my thoughts out there first so someone else could point out any flaws.

Also this is just a question, but why we are using PBKDF2 at all? Is there a need for multiple passes for this use case? As long as we are applying a salt shouldn't just HMAC-SHA be fine?

Why not public/private key cryptography?

I realise that maybe I'm out of my depth here, but if I never ask, I might never know the reason.

Why not just encrypt the data with off the shelf public/private key encryption? It appears at face value to support what you want to do without all the specialised wrapping, apart from the extra fields to support features such as TTL, the server could encrypt it's data using it's own public key and send it to the client, knowing the client cannot decrypt it anyway.

or maybe this is what it's doing and I need to learn more of the terminology?

seal() options is not guarded against mutation

If you want to change the ttl on each invocation, you can't re-use the same object since the value is not extracted from the options object until after an await.

Example:

const config = Object.assign({}, Iron.defaults);

config.ttl = 42;
const promise = Iron.seal(object, secret, config);
config.ttl = 4200;
const sealed = await promise;

The resulting object will be sealed with a ttl == 4200.

I suspect there are similar issues with unseal() as well.

TTL is not working ....

        var Iron = require('iron');

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

        var password = 'some_not_random_password';

        var defaults = JSON.parse(JSON.stringify(Iron.defaults));

        defaults.ttl = 2;
        defaults.timestampSkewSec = 1;

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

            console.log("IRON..");
            console.log(sealed);
            setTimeout(function(){
                Iron.unseal(sealed, password, Iron.defaults, function (err, unsealed) {
                    console.log("IRON..");
                    console.log(err);
                    console.log(unsealed);
                });
            },2000);

        });

Sorry i may be wrong. In this sample it should show TTL error in unseal operation with Iron.defaults.
its showing TTL error if i used defaults in unseal...

Salting + IV

Just a question that might stem from a flawed understanding of crypto. Why is iron salting the encryption key when we already have an iv, which as far as I understand is the way the algos are designed to add a random element? And isn't it redundant to salt the signature key when crypt-with-iv already should ensure that the encrypted data we're signing isn't solely determined by the plaintext data?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.