JCryption - JavaScript data encryption
jcryption.org
jcryption.org
I will send a Matasano poster to anybody who posts a valid flaw in actual implementation of this library, excluding the fatal design flaw of delivering encryption code via Javascript to browsers.
I'll get you started (I've already got a poster): this library uses PHP's builtin mt_rand() to generate keys.
I see a lot of sites use HTTP basic auth to do usernames/passwords (especially startups). Or worse, they send it over the clear (for e.g., some very popular APIs out there which I shall not name). Their reasons vary but typically it is one of cost and convenience. It is of course a terrible practice.
Compared to HTTP basic auth, this seems less evil. In this case, with no implementation issues, I assume you need an active attacker. With HTTP basic, you can just grep logs and decrypt credentials.
This seems the lesser of two evils.
Please be gentle :-)
For example, if the key and JS are provided by the server, then it is the same as basic auth (all data needed to obtain the plaintext password is in the HTTP session). If the key is generated locally on the client, you have the problem of including a good enough PRNG, seeded from enough entropy that the attacker can't guess it.
And those are all purely passive attacks (no MITM interjection). Active attacks could include modifying the JS to insert another field in the FORM POST response that is the plaintext key.
also: nice idea, modifying the js to add a plain text field to the form :P
What about if a public/private keypair is generated on the server and the public key is sent to the client? That sounds fine to me (implementation bugs notwithstanding) and it's what the second FAQ (http://www.jcryption.org/faq/) says happens.
Of course, this is still an awful idea because, as other posts have pointed out, the library itself can be doctored in transit, but I don't see a problem with the key handling design.
I'm assuming most people who would choose to use this library will just copy his example code and use 256 bit keys, which are very easy to factor.
this says in the 90's a 512 bit key could be factored for under $1 million
"Mersenne Twister is not cryptographically secure. (MT is based on a linear recursion. Any pseudorandom number sequence generated by a linear recursion is insecure, since from sufficiently long subsequence of the outputs, one can predict the rest of the outputs.)
To make it secure, you need to use some Secure Hashing Algorithm with MT. For example, you may gather every eight words of outputs, and compress them into one word (thus the length of the output sequence is 1/8 of the original one)."
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/efaq.html <-- And since that's the "Mersenne Twister Home Page", I'll take his word for it. :-)
So, looking at the PHP source code for mt_rand():
PHPAPI php_uint32 php_mt_rand(TSRMLS_D)
{
/* Pull a 32-bit integer from the generator state
Every other access function simply transforms the numbers extracted here */
register php_uint32 s1;
if (BG(left) == 0) {
php_mt_reload(TSRMLS_C);
}
--BG(left);
s1 = *BG(next)++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680U;
s1 ^= (s1 << 15) & 0xefc60000U;
return ( s1 ^ (s1 >> 18) );
}
Which doesn't seem like it qualifies as a cryptographically secure implementation; I don't see any Secure Hashing going on.If you need secure random numbers in PHP, the best advice I have off the top of my head is to take it from /dev/urandom.
A good place to get your bearings on this is Kelsey et al's "Yarrow" paper. My (unqualified) opinion is that the Yarrow CPSRNG is awkward, but the paper is a good survey on what design tactics go into a modern CSPRNG --- in particular, entropy collection and refreshing, both of which PHP's MT lack.
You're not going to use it for a banking website, but saying it's useless as you seem to be, seems odd to me.
I came across this attempt: http://tim.dierks.org/2007/03/secure-in-browser-javascript-p...
But Billy Hoffman disapproves: http://www.webappsec.org/lists/websecurity/archive/2008-01/m...
So far as I know, there's no cross-platform way to get secure random numbers from Javascript.
You can, for instance, get them from Mozilla from the "crypto" interface.
This is another reason why Javascript crypto is a bad idea.
Just my though, if this type of security is needed, why forego SSL?
Not sure if I totally buy that - if you are collecting data you want to protect, surely it's worth it for you to use a host that's capable of installing SSL. It's a pretty simple operation.
By doing a mitm interception with a newly injected public key and re-encrypting with the real key before sending to server, you can let the client-server carry on a conversation as usual, while you intercept the entire conversation.
[Client] ---(fakekey)---- MITM ----(realkey)---- [Server]
More comments about how they used RSA? Fire away, I'll send you a poster. They're pretty neat, if bigger than I expected.
They just pass the plaintext right through to RSA. No OAEP, just bang right into the BigInt. There's some random gibberish appended to the plaintext ("hey, this needs some salt"), but they're not padding a damn thing. Bleichenbacher's chosen-ciphertext attack; game over.
The RSA decryption, server-side, isn't blinded at all. Timing attack free-for-all there. Boneh's timing attack might work, as long as you can pin the session down. (And since this is for folks who don't get SSL, I'm sure you could.)
And key generation is equally horrible. The lack of a real CSPRNG was pointed out by someone else. They're also not protecting against Fermat factorization: when they generate p and q they only check equality and primality, not distance. Same with small decryption exponents. Unlikely to be serious, but it sure doesn't speak to their skills as cryptographic implementers.
Jesus H. Christ. What a train wreck.
The timing attack thought is great; would love to have an easy target for a classroom demo. Thanks!