Cryptico.js - strong encryption system utilizing RSA and AES for javascript
cryptico.wwwtyro.net
cryptico.wwwtyro.net
Then, I looked to see if the standard constant-time comparisons were in there to resist timing attacks. No dice there.
So... cool. He put a nice wrapper on JSAES[1], jsSHA2[2] by way of webtoolkit.info[3], RSA and ECC in Javascript by Tom Wu[4], and seedrandom.js by David Bau[5].
But then then says it's "New BSD license"[6] when it should be GPL[7].
I didn't start this comment sound negative. But, I think a few things are important:
* Credit authors.
* Respect their licenses.
* Put a big fucking notice on top of your slick webpage: "FOR DEMONSTRATION PURPOSES ONLY-- NOT REAL CRYPTO"
[1] http://point-at-infinity.org/jsaes/ [2] http://anmar.eu.org/projects/jssha2/ [3] http://www.webtoolkit.info/javascript-sha256.html [4] http://www-cs-students.stanford.edu/~tjw/jsbn/ [5] http://davidbau.com/archives/2010/01/30/random_seeds_coded_h... [6] http://code.google.com/p/cryptico/ [7] http://code.google.com/p/cryptico/source/browse/trunk/aes.js
The one thing I can say about the JS cryptography is that it normally protects somewhat against passive sniffing attacks, but when it's as broken as this, it doesn't even accomplish that task.
This sort of thing seems chronic in the industry, and it's dismaying.
Management made the decision that my trivial change to eliminate replay attacks was "too much effort". I am inclined to agree, since even with such a change the effort required to circumvent their entire so-called security is minimal.
Next quarter they're introducing e-commerce solutions. Dear god.
But it is written as browser Javascript and is thus totally boned. Here's my attempt to be exhaustive about why:
The passphrase almost certainly doesn't have 1024 bits of entropy in it, and since they describe it as "used to repeatably generate this RSA key", they can't have introduced any additional entropy. And indeed, they just use the SHA256 of the passphrase to seed a PRNG.
They claim that a PublicKeyID "can be used to uniquely identify Sam's public key". Fingerprints help identify keys more easily, but certainly not "uniquely" since they don't have as many bits as the key; pigeonhole principle.
Worse, the PublicKeyID uses MD5.
They use a public exponent of 3, rather than the usual 65537 or larger. It looks like they might protect against small-exponent attacks, but I don't have enough expertise to know that for certain, and in any case this seems like a bad idea.
Neither cryptico nor the rsa-sign library they use mentions anything about HMACs; I haven't dug into the code to figure out if they actually use one or just use a hash directly.
Probably piles more, but I stopped there. :)
Of course, not verifying the padding also means the signatures are straightforward to forge.
(Ping me with a shipping address and I'll send you swag).
One little nitpick:
> What systems programming functionality does Javascript lack?
Here's a starting point: a secure random number generator.
Chrome has actually implemented one (http://blog.chromium.org/2011/06/new-chromium-security-featu...). It's a part of WebKit (http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-Feb...).
Firefox has an unimplemented (as of Firefox 6) secure RNG API (https://developer.mozilla.org/en/JavaScript_crypto, https://bugzilla.mozilla.org/show_bug.cgi?id=440046).
http://rdist.root.org/2010/11/29/final-post-on-javascript-cr...
"actually, i think an honest look at the security/privacy mechanisms provided by today’s tools precisely describes a case where ‘a little better than awful’ would be preferred. my mother emailed me some bank account information just last week. there isn’t any exploit required there. security software experts have failed horribly to provide tools that actual living breathing human beings might use and this is why most of them have just given up and use hotmail.
i personally find it astounding that the kind of people who will deny this probably have an actual brand new credit card sitting in their unlocked mailbox and feel perfectly comfortable with this fact.
your information’s security is only as strong as it’s weakest link. this includes the locks on your home, your mailbox, and the granularity you shred your trash with."
Yes, in this case, bad crypto can make a bad situation worse: it can create a false sense of security.
And in the general case, bad crypto does much worse things than that. Logging in without a password. Flipping bits in a cookie to become any user on the system. Gaining admin privileges. Spoofing authorities to collect secrets from users.
Bad crypto does not care how horrible your mom has it. Engineering says, bad crypto is going to be bad no matter how hurt your feelings are.
Moreover, for noncritical things, like my example of fantasy football plans, this appears to be a perfectly reasonable solution.
// For best results, put code like
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
// in your main HTML document.
And if one doesn't...(Ping me [see profile] if you want a sticker for finding that issue. They're neat!)
var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
(Just a pity the signature verification function is broken by it.)And if this JS code is transferred over https, what's the point of it? Don't we already have crypto in this case?
You cannot verify the integrity of a browser Javascript cryptosystem by checking a SHA2 hash of the Javascript file containing the crypto.
That's because any other piece of content, from Ajax requests and whatnot to, in many browsers, the CSS files, some of them cached and some of them loaded on the spot... any other piece of content that contributed to the page that hosts the crypto code can alter the runtime to trivially intercept secrets or fix keys.
Until browsers provide a primitive to verify the whole runtime, cryptographic hashes won't do anything to ensure integrity for Javascript.
Javascript sent over the Internet in cleartext is trivial to intercept and alter.
I threw together my own implementation of that from scratch when it hit hacker news a few months ago. Mine uses an arbitrary sed script, not sure what theirs does but I believe they've released their source now.. It took about 2 hours max.
Deploying it? Seconds.
I think there are probably some novel solutions to this problem, but it would require work to be done by the browsers.
But it means that we're not going to have end-to-end crypto in web applications for another ten years, because these schemes don't degrade gracefully; the majority of users will have to upgrade before they become useful.
x = new Cipher("AES");
x.blockmode = "CBC";
// defaults to all zeroes
// x.iv = "ABCDABCDABCDABCD";
x.key = "YELLOW SUBMARINE";
x.encrypt << "This is my plaintext";
In a sense, this is great news for me, because it means I get another 5-10 years of crypto vulnerabilities to get paid to eradicate. But if you're hoping for simple, usable cryptographically strong security in common web apps... well, keep hoping.- Writing crypto systems in dynamic languages is hard/impossible
- There is a need for browser based crypto
- The browser manufacturers are moving too slowly in this regard
I would love to see reasonably secure browser based crypto. You could submit things to a website without the website being able to see what they are.
Imagine a social network that was opaque to the people hosting the social network.