7 ms·
It's Dangerous, a Python cryptographic signing module
- obiterdictum 14y agoExecutive summary: - The signature: SHA1 HMAC of data and, optionally, a timestamp to expire signatures. - HMAC key derivation: SHA1 of a secret key and a salt.
- JoachimSchipper 14y ago> - HMAC key derivation: SHA1 of a secret key and a salt. Note to non-cryptographers: do not use low-entropy (password-ish) secretswith this, they can be bruteforced. (Using bcrypt/scrypt/PBKDF2 instead would fix this.)
- deleted 14y ago[deleted]
- ibotty 14y ago... when will they ever learn...
- the_mitsuhiko 14y ago> ... when will they ever learn... When will some people on hackernews ever learn to start using their brain. PBKDF2 is not what you use to verify signatures. I think the name should already give that away. //EDIT: and when will I ever learn to read properly. I just realized that the comment was referring to the "salt" part, not the signature.
- the_mitsuhiko 14y ago> Note to non-cryptographers: do not use low-entropy (password-ish) secretswith this, they can be bruteforced. (Using bcrypt/scrypt/PBKDF2 instead would fix this.) PBKDF2 for this would be possible, but a terrible idea. The reason why PBKDF2 works for password verification purposes on web apps is because you can rate limit the login entry point. Doing that for sessions or activation links like what you would use itsdangerous for is an easy way to have other people DDOS your app. PBKDF2/bcrypt etc. is not the solution for this problem.
- JoachimSchipper 14y agoLet me expand a bit: use bcrypt etc to derive the key instead of using a salted hash, then use HMAC to sign the data. You're right that using bcrypt for every request would be really bad for performance, but it's a per-app password, so you can just do run bcrypt once, at startup. (Alternative: drop the SHA1/bcrypt/whatever and just use a really strong secret key. 128 bits of randomness is impossible to brute-force.)
- the_mitsuhiko 14y ago> but it's a per-app password, so you can just do run bcrypt once, at startup. itsdangerous has nothing to do with passwords. It's about signing small messages and these messages are obviously created at runtime. > nonsense and just use a really strong secret key That's how you should use itsdangerous: use a strong secret key.
- Luit 14y agoOne way to get a good strong secret key for this purpose: $ python >>> import os >>> os.urandom(64)
- amalcon 14y ago/dev/random is better than urandom for this sort of thing. On linux: dd if=/dev/random bs=64 count=1 2>/dev/null | hexdump
- tcas 14y agoYou shouldn't use urandom for crypto purposes. /dev/random is generated (on most platforms) as cryptographic strength numbers (usually from hardware), but can block if it runs out of data. /dev/urandom was created with the guarantee to never block and will use /dev/random's pool of numbers initially but can start outputting lower entropy numbers if /dev/random blocks.
- JshWright 14y agoIf rate limiting login attempts was all it took to protect passwords, then it wouldn't matter what hashing function you used, since the rate limiting would be independent of that. The point of PBKDF2 and friends is to make it expensive to brute force acquired hashes. It effectively 'rate limits' hash-in-hand brute force attempts. It's designed to protect hashes once they are in hostile environments. The use cases you described (session keys, activation links) are the perfect example of such environments.
- Locke1689 14y agoThere should be no password at all involved. You're doing key signing, not password authentication. You should have a tool, like OpenSSL or GPG, generating your key pair for you. And people, STOP USING CRYPTOGRAPHIC PRIMITIVES FROM THINGS THAT ARE NOT OPENSSL.
- tptacek 14y agoAroo? OpenSSL is usually a terrible place to pull crypto primitives from; the string "OpenSSL" in a Python or Ruby file is a decent predictor of crypto bugs. Also, OpenSSL has a relatively poor track record of algorithm-level bugs. I'd like your sentence more if it read "STOP USING CRYPTOGRAPHIC PRIMITIVES" and then ended with a period.
- Locke1689 14y agoI took that from cperciva when he did his crypto talk. Edit: Found quote: Website security: Use OpenSSL. OpenSSL has a horrible track record for security; but it has the saving grace that because it is so widely used, vendors tend to be very good at making sure that OpenSSL vulnerabilities get fixed promptly. I wish there was a better alternative, but for now at least OpenSSL is the best option available. UPDATE: For added security, terminate SSL connections in restricted environment and pass the raw HTTP over a loopback connection to your web server. And yes, I'd always recommend using the highest-level possible API. If you have SHA in your code you are probably working at too low a level. Do you have any recommendations for a better toolkit? Tarsnap uses Colin's own implementations so it's not a very good resource. There are other problems I've found with cryptlib, etc., (e.g., cryptlib is commercial).
- ctz 14y agoUse of SHA-1 for this signature/MAC purposes in new applications is deprecated and will be disallowed from next year (source: NIST). I repeat: do not use SHA-1 in new applications. Do not use this module.
- jacques_chester 14y agoTo clarify very slightly, use SHA-256, SHA-384 or SHA-512 instead. Sometime soon I believe SHA-3 will be chosen and we'll all be able to move onto that.
- fluffyllemon 14y agoFor those interested, NIST (National Institue of Standards and Technoology) announced a competition to find candidates for the SHA-3 algorithm back in November 2007: "NIST also plans to host a final SHA-3 Candidate Conference in the spring of 2012 to discuss the public feedback on these candidates, and select the SHA-3 winner later in 2012." [http://csrc.nist.gov/groups/ST/hash/sha-3/Round3/index.html http://csrc.nist.gov/groups/ST/hash/sha-3/Round3/index.html] The final SHA-3 Candidate Conference was held March 22-23, so they should be picking the winner any day now.
- Luit 14y agoWell then fork it and make it use HMAC with SHA256/512... Additionally, "Do not use this module" is bad advice if it leads to someone making their own MAC implementation, because that's almost always a bad idea. HMAC-SHA1 still is good security for this purpose. I bet that as soon as standards bodies (like NIST) actively encourage you to use better hash functions (which they will probably do soon) the developer of this module will decide on what is safe enough for this purpose.
- ch0wn 14y agoIt shouldn't be more than changing those two lines: https://github.com/mitsuhiko/itsdangerous/blob/59f3bf7877e21af8e5571993edb6834744858583/itsdangerous.py#L107 https://github.com/mitsuhiko/itsdangerous/blob/59f3bf7877e21... And the tests, of course.
- __alexs 14y agoDo we really need an entire library to encapsulate http://docs.python.org/library/hmac.html http://docs.python.org/library/hmac.html and string.rsplit?
- tptacek 14y agoYes, because Python's "hmac" library doesn't provide a secure "verify" method.
- __alexs 14y agoIs == not good enough for you?
- tptacek 14y agoSigh. http://codahale.com/a-lesson-in-timing-attacks/ http://codahale.com/a-lesson-in-timing-attacks/ Preemptively: * Yes, a realistic attack. * Yes, very difficult over the Internet. * Still difficult but not implausible if the attacker can colocate near your app; ie, if you deploy anywhere on EC2. * Measurement bounds are high nanoseconds LAN, tens of usecs WAN. * HMAC verification, unlike password hash comparisons, is a place where timing actually does matter. Not to suggest that I occupy the high road when it comes to snarky comments, but consider whether your snarky comment in this case suggests an unearned (and thus dangerous) level of confidence about crypto app security. This problem (HMAC timing) is so well known that it's generated many hundreds of comments over the years on HN.
- __alexs 14y agoThat's still a lot of code just to import a single 6 line function...
- tptacek 14y agoThe fact that he knew about that function and you (standing in as "representative Python developer") did not seems to justify the library pretty nicely from what I can tell. But, obviously, this code does more than Python's hmac library does, beyond just knowing how to properly verify the MAC itself.
- tptacek 14y agoThis facility is "built in" to Rails, with MessageEncryptor and MessageVerifier. Before you consider writing your own "apply an HMAC-SHA1 hash to a string" library in Ruby, just take those classes from ActiveSupport instead. They've been reasonably well tested.
- ashconnor 14y agoAlternatively, if you are not using Rails but are still using Ruby, then you can use OpenSSL::HMAC.
- tptacek 14y agoThis is a MUCH WORSE IDEA. Don't do this. Even this Python wrapper library does a better job providing HMAC services to users than OpenSSL's HMAC primitive does. Leave OpenSSL:* to the suckers^H^H^H^H^H^H crypto library implementors.
- ashconnor 14y agoThe wrapper is pretty elegant weighing in at 3 functions; it all depends on how high-level you want to go. If people are having trouble they can refer to the Rails ActiveSupport source code for help.