fernet / spec Goto Github PK
View Code? Open in Web Editor NEWSpec and acceptance tests for the Fernet format.
Spec and acceptance tests for the Fernet format.
fernet acceptance tests generate.json contains all parameters needed to deterministically generate a fernet token, as well as the token that should be generated. src: payload to be encrypted iv: 16-byte IV to use for encryption secret: base64-encoded 32-byte key to use for signing and encryption now: time to be used for the timestamp in the generated token token: value of the token that should be generated verify.json contains a valid token and all parameters needed to deterministically verify it. token: token to be verified ttl_sec: time-to-live in seconds now: current time of the verifying process secret: base64-encoded 32-byte key to use for signing and decryption src: unencrypted payload to be retrieved from the token invalid.json contains parameters for verification and a token that is invalid under those parameters, as well as a description of why the token is invalid. desc: reason why the token is invalid token: invalid token ttl_sec: time-to-live in seconds now: current time of the verifying process secret: base64-encoded 32-byte key to use for signing and decryption
Converting from the string representation is, at best, annoying, and presents a vector for mistakes in testing an implementation.
Is the Fernet spec's versioning unambiguous? The spec on current master
says:
This document describes version 0x80 (currently the only version) of the fernet format.
However, the current master
is the sixteenth commit since the doc started, and it was called 0x80 when it started, too. What did those commits change? Should some of them have bumped the version?
The current lack of tags further suggests that version 0x80 is ambiguous.
It would be good to clarify this in the readme and in the repository status.
Maybe archive it, if it isn't maintained anymore.
Thanks for all your work!
Hello.
I want to encrypt a simple text (not a byte string) in AES256 CBC.
Is it possible?
In a script I use these instruction
cipher = Cipher(algorithm=AES256(cryptoKey), mode=CBC(iv))
encText = cipher.encryptor().update(b"Ciao")
But if I cange the parameter to the update method in a simple text ("Ciao", without sign "b") I get an error from python
TypeError: from_buffer() cannot return the address of a unicode object
What can I do to encrypt a simple text?
Thanks.
I think I should insert a step between steps 1 and 2 of Verifying:
Is that right @tmaher?
I'm working on a PHP implementation that I would like to put in this project, and commit to mantain. It is passing all the acceptance tests and its developed in a way that can be extended easily when new versions come.
Let me know what you think.
In the Fernet spec, when describing the IV, it says the following: "When generating new Fernet tokens, the IV must be chosen uniquely for every token. With a high-quality source of entropy, random selection will do this with high probability."
In reality, with CBC encryption their 'uniqueness' property is neither necessary nor sufficient. Instead, they really do need the IV to be chosen by 'random selection' in order for CBC to be safe.
The implementations of Fernet token uses os.urandom(16), which is the correct way to generate an IV for CBC mode.
This means that the document must be corrected as "When generating new Fernet tokens, the IV must be chosen by 'random selection' in order for CBC to be safe."
Thank you,
Fernet is the default cipher available in python-cryptography.
This unfortunately means that it will be (ab)used for things other than just token signing.
I believe it would be prudent to stress in the README that users need provide their own anti-replay mechanisms, or at least use the ttl
attribute of decrypt()
One way for users of Fernet (or even Fernet itself) to do this would be to use a monotonic clock for sent timestamps and then enforce monotonicity for received timestamps.
What is the reason there is a base64 for output of encryption? Is it really necessary? Why wont we get rid of it and make fernet usable even for files encryption - saving approx 1/3 of storage.
here are few issues addressing this problem in implementations of fernet spec:
pyca/cryptography#8755
pyca/cryptography#4921
Hi,
I have implemented a reference implementation of fernet in pure Python. It exists also in Cryptography, however in a very in-transparent way.
This module is using pyaes and standard library modules only, so it's easier to understand if you look
for a reference implementation.
I would be happy if you officially included it here.
Is there a particular reason that a token is not verified for integrity before its timestamp is checked?
This allows attackers to discover the decrypter's valid TTL, by monitoring how long they take to verify a message.
So you have constant-time verification of valid tokens, but variable time verification of invalid tokens.
Additionally, is there a reason the spec transmits the timestamp in the clear, rather than encrypted? Surely doing the latter would make it useful to more people; and any applications or user contexts which relied on a message's send-time being private might also currently mistakenly use this protocol.
I assume time to verify a HMAC is not a problem, since tokens are url-safe base64 encoded - either short enough to be present in a url, or not long enough to worry about the storage inefficiency of base64.
I wanted to bring to your attention that Fernet currently has a dependency on the Crypto.js library, which has been discontinued. This poses potential security and maintenance risks for projects relying on Fernet.
Nowadays, Node.js and modern browsers come with a native Crypto module that provides robust and up-to-date cryptographic functionality. Could you please consider updating Fernet to utilize the native Crypto module instead of the discontinued Crypto.js library?
This update would enhance security, ensure ongoing support, and reduce dependency on outdated libraries.
Why does Fernet exist? Who made it? Where does it come from? What does it compete with? What does it replace?
The lack of precision on the creation timestamp (currently 1 second) introduces the possibility for a race condition when evaluating tokens against revocation events. If you only care about TTLs when validating tokens, then this won't affect you.
For example, imagine an event occurring that might invalidate previously issued tokens, such as a password change or a logout operation at t=0.1
seconds (note that outside the world of Fernet, we can measure time more accurately than whole seconds!). Then, the user immediately creates a new Fernet token at t=0.2
seconds. Unfortunately, that timestamp is only recorded with a precision of 1 second in the Fernet token and thus appears to have been created at t=0
(suddenly it was created before the revocation event occurred).
However, when comparing the token's rounded timestamp (t=0) to the event's timestamp (t=0.1
), we're forced to use the least precise data we have, and thus we must compare the token's rounded timestamp (t=0
) to a rounded timestamp of the revocation event (t=0
). It thus appears that both events occurred at the exact same time (which is not true), and therefore we must mistakenly consider the token to be invalid, even though it was actually created after the revocation event occurred.
By increasing the precision of the timestamp in Fernet, you decrease the window of opportunity for this race condition to occur until it is not viable to reproduce from a client's perspective. With a one second timestamp and application response times well under that, however, that window is currently relatively large.
Accordingly https://tools.ietf.org/html/rfc2104#section-3
the key for HMAC can be of any length (keys longer than B bytes are first hashed using H). However, less than L bytes is strongly discouraged as it would decrease the security strength of the function.
For SHA-256 L = 256, but spec describes signing-key with 128-bit length.
Thank you for the Fernet specification. I was a little surprised that there is no Java implementation and so I set out to implement it myself.
Please have a look at my repository fernet-java and let me know if that is sufficient to be added to your repository.
Is it possible to enhance the Fernet spec to allow the optional use of AES192/256 encryption with an appropriate flag in the version byte to indicate the encryption used? I've run into projects where Fernet would be a good fit but 256-bit encryption is required. Nothing in the current spec would interfere with allowing larger key lengths, and in the implementations I've tried it's simply a matter of setting the encryption to use the longer key and the rest of the implementation is oblivious to the change.
I would appreciate some feedback on this Java 8 implementation. Although #19 also defines a Java implementation, I sought to create one that leverages new language features in Java 8 to avoid introducing any dependencies (avoid dependency hell) and to provide better type safety (through the new time objects) when integrating with other Java code.
This implementation also makes it easy to plug in custom payload validation as well as TTL and clock skew rules.
This implementation has been tested against all of the scenarios in the spec and the effectiveness of the tests are measured with mutation testing. I also provide examples of how to use this library to secure a REST API built using JAX-RS.
I would appreciate some feedback prior to releasing version 1.0.
We found this issue when encoding a string that happened to be exactly 160 bytes in length.
The token generates, but upon .verify, it fails with a padding error.
Our guess is it would fail on any coded input that happened to have a length that is a multipler of 32 bytes.
There are other variants of b64.
Hello.
Is It possible to have the result from hmac.HMAC in binary format (as in PHP with the function hash_hmac)?
If yes, how?
I am not very expert about python.
Thanks for your help.
The spec's instructions for verifying token TTL doesn't explain how to handle nanoseconds.
If the user has specified a maximum age (or "time-to-live") for the token, ensure the recorded timestamp is not too far in the past.
This results in difference between implementations. For example, fernet-go uses time.Time.After
, which checks equality down to the nanosecond level, while Python's cryptography.fernet truncates nanoseconds from the now timestamp before comparing. This means that a token may fail verification in one implementation, but pass in the other.
Last commit seems to be three years ago. Is it safe to assume spec is not maintained anymore?
There's a test case in invalid.json
for this, but it's not in the spec at all as far as I can tell
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.