

Javascript encryption - aberatiu
http://www.vincentcheung.ca/jsencryption/

======
acqq
John Walker made that already at least 6 years ago:

<http://www.fourmilab.ch/javascrypt/>

Moreover, Walker's code is public domain and he discusses security aspect,
whereas the op link appears not to care about such things.

~~~
d0ne
Similarly with Movable-Type's implementation: <http://www.movable-
type.co.uk/scripts/aes.html>

<http://www.movable-type.co.uk/> contains several very useful resources for
implementing JS crypto.

~~~
tptacek
... which, implementing JS crypto, you should never do.

~~~
d0ne
If your goal is to share state secrets, then no, I wouldn't suggest using JS
for crypto.

If your goal is to no longer be low hanging fruit for attackers, then yes, I
would recommend it.

~~~
tptacek
The terminus of your argument admits to using ROT13 as a cipher. Surely
there's some attacker ROT13 bars. While you're at it, Base64 the "ciphertext".
There are professional pentesters that can't recognize Base64 on sight! And if
you want to get really tricksy, swap the Base64 alphabet around. That'll hoist
that fruit up higher.

In reality, no credible cryptosystem accepts the flaws I'm talking about.

~~~
jrockway
That's true, but I'm not sure everyone should be quite so defeatist as you
with respect to implementing crypto. It has and can be done, after all, it
just requires care beyond "hey, my PHP script outputs some HTML." The same
goes for many, many aspects of programming: design, object lifecycle, memory
allocation, error handling, etc. Programming is hard, and implementing crypto
is no different. The difference is that mistakes are not immediately obvious
and that they can be severe. But that, again, is the case with many things.

~~~
thaumaturgy
If there's anything I've learned so far after observing the security world for
a few years, it's that implementing crypto is _very_ different. I think that
this mindset from programmers -- "crypto is just like programming" -- is what
causes them to constantly, and almost without fail, screw up their password
storage systems, their authentication mechanisms, their crypto functions, and
pretty much everything else security-related.

Software development in general tolerates (and in some ways even encourages)
"acceptable risk". Programmers don't often try to _prove_ that their functions
are correct and free of any potential errors. In security-related programming,
you can't take the same approach.

Implementing crypto is very, very different. If you're "iterating" the design
of your crypto functions, you're doing it wrong.

~~~
jrockway
The reason people screw up password storage is because they don't know they
are supposed to think about it. If they flipped the "oh, this is important"
switch, the result would be better. But at the end of the day, their bosses
are asking them for shiny widgets, not a secure backend. So they are doomed to
fail.

The same goes for the non-security things I've listed. The problem is much
deeper than getting crypto wrong -- most programmers today get _everything_
wrong. That's why I think if you're the type of person that can think about
programming, it's not too unsafe to implement AES in Javascript and use it.
You know what the weaknesses of Javascript-based crypto are, and you know how
to implement crypto. In that case, why not do it?

Remember: most non-crypto software is massively incorrect. If we can trust
people to implement crypto, why can we trust them to be programmers at all?

~~~
thaumaturgy
I think I see where you're coming from, but I still disagree: I've seen way
too many examples of otherwise competent programmers still stuck on, for
instance, the notion of using salts with fast hash functions for password
storage. Hell, MtGox had a post just the other day about their all-new
_triple-salted SHA256 password storage!_ Somewhere that day, there was a faint
groan from the dismally small set of people who are knowledgeable in password
storage and are interested enough in Bitcoin to have read about that.

The difference between bugs in non-crypto software and bugs in crypto software
is that bugs in crypto software can have much more severe and far-reaching
consequences. So, while I might trust a programmer to write decent non-crypto
software, I would prefer not to trust them with writing crypto software.

edit: actually, there's more to it than that, on second thought. Crypto also
requires a greater depth and breadth of expertise. The math knowledge required
for general programming is trivial by comparison; about the worst it usually
gets is vector-based math, or simple calculus, or big-O notation. But to
understand crypto well enough to implement it correctly requires a much
greater knowledge of mathematics -- something which most programmers don't
have.

> _You know what the weaknesses of Javascript-based crypto are, and you know
> how to implement crypto. In that case, why not do it?_

Because I (the rhetorical "I" in this case) know what the weaknesses of
JavaScript-based crypto are. :-)

------
dguido
Relevant: [http://rdist.root.org/2010/11/29/final-post-on-javascript-
cr...](http://rdist.root.org/2010/11/29/final-post-on-javascript-crypto/)

The killer for me has always been #7 on Nate Lawson's list: Auditability. How
do you tell that your browser is using the right copy of the code to do the
crypto?

~~~
antimora
This is an excellent article on this subject. The author (Nate Lawson) is
thorough in his argument. His conclusion is "I am certain JS crypto does not
make security sense."

------
antimora
Could anyone explain what's the use case for encrypting text on a web page
using JavaScript? I don't understand how this library is useful except for
situation when used in Chrome extensions like the one used by LastPass.

If this lib is used on a page to decrypt/encrypt user data before sending to
the server, theoretically it's possible for the host to steal private key
simply by injecting a JS code that copies user's private key.

~~~
tptacek
It's worse than that. Among many other things, it's possible for any attacker
with an XSS bug in any component of the DOM of that page (cached or fetched
fresh) to steal keys. Modern browsers provide no way to verify the whole JS
runtime to ensure that no function that your crypto depends on has been
backdoored, but every JS implementation allows functions to be overridden.

It's the worst possible environment to implement crypto in, and you should
never do it.

~~~
DenisM
XSS is in your own control (as a site owner/developer), and it is less likely
to happen than the user machine being infested with malware to begin with. And
the malware infestation threat has never stopped anyone from advocating native
(non-browser) crypto, right?.

~~~
thaumaturgy
Your argument here looks like, "other things have vulnerabilities, and
JavaScript has vulnerabilities, so it is equivalent to other mechanisms."

If that is your argument, then the conclusion is wrong, because JavaScript
implementations are vulnerable to everything that everything else is
vulnerable to, _and then some_.

There is _nothing_ that a JavaScript implementation actually protects you
from.

~~~
DenisM
That's not my argument at all. My argument is that the probability of a well-
designed site having XSS (p1) is much less than that of a user's machine being
infested (p2). When you start using both, as you say, we end up with compound
probability of a breach p1+p2, which is strictly worse than p2, but if p1<<p2
we are not losing much to begin with, and it maybe justified if we're gaining
as much or more elsewhere.

In other words, global optimization may require local pessimization.

E.g. if we gave the user ability to store secret data without the key ever
leaving his possession, he might be more likely to use the service and stop
storing his secrets in a notepad file. However if we don't guarantee that the
key will not leave the user's possession, the user may decide not to use the
service.

~~~
thaumaturgy
> _...and it maybe justified if we're gaining as much or more elsewhere._

Except that, in terms of real security, we aren't. That's the whole point.
You're right in describing it in the way you did, but then you get to this
point where there's this implicit assumption that JavaScript-based crypto
gains you something. Which, maybe, leads into your next point...

> _E.g. if we gave the user ability to store secret data without the key ever
> leaving his possession, he might be more likely to use the service and stop
> storing his secrets in a notepad file._

OK, but this is a different problem. The _correct_ solution here is a true
client-side app or a browser add-on (and even then ... ehhhh). Otherwise --
and this is a point that I don't feel like I can emphasize enough -- you are
giving your users a completely false sense of security. You're selling a
service by saying that "we'll store your secrets for you and you don't even
have to ever give us your key, so it's more secure than keeping them in a
notepad file", but that's demonstrably false.

> _However if we don't guarantee that the key will not leave the user's
> possession, the user may decide not to use the service._

Also a different problem. _You can't sell security this way._ All you're doing
is taking advantage of people's ignorance. If everybody understood the
security risks of JavaScript-implemented crypto, and you sold _the same
service_ \-- "we use JS so you never have to share your keys" -- then the
users would decide not to use the service!

To reiterate:

1\. Server-side encryption is a real protection from accidental or malicious
data leaks (db dumps);

2\. SSL is a real protection from MITM and eavesdropping (mostly, with
caveats);

3\. If the server software gets compromised, you're pooched no matter what.

So, again: JavaScript solves _none_ of these problems.

The only thing that JavaScript does, is add more problems.

~~~
DenisM
>You're selling a service by saying that "we'll store your secrets for you and
you don't even have to ever give us your key, so it's more secure than keeping
them in a notepad file", but that's demonstrably false.

Now, aren't you getting carried away? Physical loss of a laptop will
compromise the notepad file, but not the client-side encrypted data. Malware
on the laptop will compromise the notepad file 100%, but any crypto-based
solution will only be compromised if it's been used during that time.
Fire/flood/theft will deprive the user of his secrets altogether.

Seriously, are you claiming that a notepad file is more secure than a server-
based storage with client or server encryption? That's an extraordinary claim.

~~~
thaumaturgy
Yes, I am making that claim.

Especially since:

1\. That notepad file can be encrypted on the laptop; and

2\. "Web app" programmers so often get security really wrong. This entire
thread is just one of a huge number of examples of that.

Honestly, any hosted solution that relied on JS for encryption or
authentication would encourage me to keep storing secrets in text files on my
laptop.

Here's a fun, easy way to understand why hosted solutions are rarely a good
idea for storing private data:

\- Make a chart with four columns;

\- Column 1 is "Unencrypted local storage"; column 2 is "encrypted local
storage"; column 3 is "remote storage with JavaScript encryption"; column 4 is
"remote storage with SSL + server-side encryption";

\- Under each column, write down a list of every method you can think of that
that particular system could be broken. Take your time and be creative.

\- Cross out any methods that all of the columns have in common.

\- Compare the results.

------
oconnore
Be careful: if you are using a javascript library to encrypt data, you get
protection from eavesdroppers, but not from man-in-the-middle attacks. If I
can alter data that you send/receive over the wire, I can simply modify your
aes function calls to xor the data with a predictable sequence that I
generate. The only way to prevent this that I have thought of is to store the
site (which has presumably already been acquired over a secure channel)
locally on the client's machine, and make AJAX calls over the encrypted
channel for fresh content.

~~~
thaumaturgy
> *...if you are using a javascript library to encrypt data, you get
> protection from eavesdroppers..."

Nope. Replay attacks. Piece of cake.

The number of things that JavaScript does better than SSL is 0.

~~~
oconnore
I don't think you know what you are talking about. If your authentication is
implicit in the decryption of the messages, replaying that data will
accomplish nothing.

For example, if I share a secret "password" with my server, I can do this in
javascript using any symmetric cipher:

    
    
        ToServer: "My name is oconnore"
        ToClient: cipher(iv1, "(C1) Hi oconnore. Use this! iv2=rng()"++msghash, "password")
        ToServer: cipher(iv2, "(C2) Thanks, give me my data please!"++msghash, "password")
        ToClient: cipher(iv3, "(C3) <Some data>, and iv4=rng()"++msghash, "password")
        ...
    

If an attacker repeats any of these messages, the client/server will discard
them based on the counter. Of course, for real use you would need to use
public key crypto to avoid storing passwords in what is essentially plaintext,
but I thought this would illustrate how replay attacks are a non issue.

Of course, as noted before, all this is irrelevant if you are sending your
code over a channel vulnerable to MITM...

------
antihero
What does this offer over SJCL?

And for those asking in the thread, JS encryption is useful in that you never
have to trust a server with your plaintext.

~~~
gorset
If you are running javascript on a page from a server, you are trusting the
server with your plaintext.

~~~
Acorn
Seems like browser extensions would be the way to go.

Here's the SJCL demo: <http://bitwiseshiftleft.github.com/sjcl/demo/>

~~~
dublinclontarf
SJCL has a bug in their RSA implementation. We're using a good bit of their
code with a few changes for our web client. The idea being that we don't want
to store passwords, so the webclient stores an encrpyted private key and
everything sent to the server must be signed.

The users id is a sha256 hash of their public key and all we keep are the
public keys.

Working so far in FF and Chrome, not even trying it in IE

~~~
xfax
Are you at liberty to disclose what you're using this for? i'm interested in
learning about legitimate use cases for SJCL.

~~~
dublinclontarf
The auth system for a stock/asset exchange.

------
st3fan
Looks like a nice implementation. But I would feel more comfortable if it had
some tests to show that the AES test vectors all pass.

------
KonradKlause
Snakeoil

