1
vote
$\begingroup$

A friend of mine needed help with her website and asked how to send me her login information securely. I've never known how to do this, so I figured now was the time to learn. After some googling, I suggested sending me an SMS or a password-protected zip file. Then, just for fun, I programmed this:

<html>
<head>
<title>AES Encrypt/Decrypt Page</title>
<script src="http://herbaloutfitters.com/cryptojs/rollups/aes.js"></script>
<SCRIPT LANGUAGE="JavaScript"> 
function aes_enc(form) {
  var encrypted = CryptoJS.AES.encrypt(form.thetext.value, form.passkey.value);
  form.thetext.value = encrypted;
}
function aes_dec(form) {
  var decrypted = CryptoJS.AES.decrypt(form.thetext.value, form.passkey.value);
  form.thetext.value = decrypted.toString(CryptoJS.enc.Utf8);
}
</script>
</head>
<body>
<form method="POST">
<textarea name="thetext" rows="11" cols="35"></textarea><br>
Passkey: <input type="text" name="passkey" size="16"><br>
<input type=button name=enc value="Encrypt" onClick="javascript:aes_enc(this.form)"><br>
<input type=button name=dec value="Decrypt" onClick="javascript:aes_dec(this.form)">
</form>
</body>
</html>

See the above code in action here: herbaloutfitters.com/crypto.html

My question is: how secure is this? Is it more or less secure than the SMS or zip file solution? Is there a better way that's easy enough for the average person to use without much greater difficulty than these solutions? (I thought about encrypting gmail or Thunderbird, but these seemed more time-consuming. The average person would probably not want to bother.)

EDIT:

  1. People have requested I define "secure." I thought people might ask that, so that's why I asked to compare to the security of SMS and password-protected ZIP file. Of course, nothing is ever truly secure. Phones can be tapped, people overhear, emails read, etc.

  2. One person cited that one'd be at the mercy of a third-party by using their code. In this case, I d/led it to my server and inspected it for malicious code. Anyone using my page could do the same.

  3. Why not give the info over the phone? That seems less secure, doesn't it?

  4. AES requiring both sides to have the same key, and if you have a channel to securely exchange a key, you have a channel to securely exchange the original message. True, but the key could be provided via hinting at something only the two parties know. Not all that secure, I know, but in this use case, I've found public-private key encryption is too difficult for people to understand. They'd get frustrated and go back to unencrypted email or a phone call.

  5. Encrypted IMing. This might be more secure, provided I trust the developer AND the client is willing to go through the trouble of installing the software. Usually neither is the case. Basically, what I'm looking for is the easiest way to transfer login info in the most secure way possible that's still convenient to actually be used by real world clients unfamiliar with encryption and the more technical aspects of computers. The above page I programmed (plus SMS) is my solution. (Many would also have trouble with password-protecting a zip file.) I'm just wondering if I've made a gross miscalculation in how secure it is by overlooking something, given how little I know about network security.

EDIT to address being put on hold: I believe my initial question was specific enough but may appear non-specific because I chose to address the proposed solutions, which made it appear as though I was asking for other solutions. No, my question is specific to the particular code I wrote, asking how it compares to the security of SMS and a password-protected zip file. That's all. I know there are more secure ways to transfer login info, but I am not interested in that in this question. I just want to know if there's a glaring vulnerability in my own specific solution. I am also not interested in the definition of "security," as that would also be too broad. As long as my solution is reasonably secure (as determined by comparing it to known, reasonably secure solutions, like SMS and a password-protected zip file), I will be happy.

$\endgroup$
7
  • 2
    $\begingroup$ Could you please define secure ? How much risks are you willing to take ? :) Why can't she call you by phone and give you the login / password ? $\endgroup$
    – Biv
    Commented Mar 20, 2016 at 1:58
  • $\begingroup$ The risks are completely different than with e.g. SMS, but comparing those is more of a security policy question (which are often moved to Security.SE). If that JS is from someone else's website, you essentially give them complete control over what happens. $\endgroup$
    – otus
    Commented Mar 20, 2016 at 12:07
  • $\begingroup$ @Biv, otus, thanks. I've amended the original question to address your points. $\endgroup$ Commented Mar 20, 2016 at 20:58
  • 1
    $\begingroup$ I am afraid that you're widening the scope of the question too much with the edit. I will point out that most of your concerns depend heavily on who is your adversary. A random attacker on the Internet? Then your server exposed to the internet is probably more vulnerable than the phone network. A tech-savvy friend of yours? Then a third party application will be more reliable than any code you can spontaneously produce. A government "big brother" entity? Then any "hint" you share will probably help them to break the scheme. $\endgroup$ Commented Mar 20, 2016 at 21:06
  • $\begingroup$ See: tonyarcieri.com/whats-wrong-with-webcrypto JS is never trusted code over HTTP. If HTTPS is in use the need for JS encryption vanishes. $\endgroup$
    – marstato
    Commented Apr 18, 2016 at 17:34

5 Answers 5

3
votes
$\begingroup$

in practice

A friend of mine needed help with her website and asked how to send me her login information securely. I've never known how to do this

The current best-practices way to let you access someone else's website is using SSH, the Secure Shell.

Send your public key to that person (in the open, with unencrypted email or etc.). Then have that person confirm it really is your public key (there are a variety of ways of checking). Then have that person log in to the website (perhaps using ssh) and append your public key (typically in a file named "id_rsa.pub") to the end of the "~/.ssh/authorized_keys" file in that account on the website.

That authorizes you to log in to that account using ssh in the normal way, using only your own private key and without knowing your friend's password or private key, and without your friend or anyone else knowing your private key.

http://en.wikibooks.org/wiki/Internet_Technologies/SSH has some step-by-step tips on how to create a private key (if you don't already have one), derive the corresponding public key from it, copy it to a remote server, log in with ssh, etc. (The Information Security site is another place to ask for information about using ssh).

in theory

Your friend can encrypt the login information and send you the encrypted package. But how are you going to decrypt that package? You need the decryption key for that, right?

If you ever discover a way to securely send that decryption key -- why don't you send the login information directly the same way?

You have discovered the one problem with the one-time pad and with symmetric cryptography in general: the key exchange problem.

If you're just doing this for fun, you might consider using "t=n: trivial secret sharing", using XOR to create a set of messages sent through a variety of paths (a few messages sent through separate emails, IMing, phone calls, etc.) so that the only way to reconstruct the login information (or the decryption key) is to get all of the messages. But there are better methods.

In practice, the best solution we have so far to the key exchange problem is asymmetric cryptography, also called public-key cryptography. The RSA algorithm (the "rsa" in the "id_rsa.pub" mentioned above) and Diffie–Hellman key exchange (D-H) are currently the two most popular and widely-used asymmetric cryptography techniques. The clever part about D-H is that it doesn't actually send the secret key from Alice to Bob or from Bob to Alice -- instead, the algorithm generates a fresh new secret key from the (publicly transmitted) random bits Alice and Bob send each other, in such a way that Alice and Bob both end up with a copy of the key, but no one else listening to their conversation can get a copy of that key.

$\endgroup$
1
  • $\begingroup$ You'd still need to trust the public key somehow. One way would be to send it over TLS. Otherwise you'd just be protected against eavesdropping, not active attacks. And if eavesdropping is possible, then usually so are active attacks. $\endgroup$
    – Maarten Bodewes
    Commented Nov 23, 2017 at 13:53
3
votes
$\begingroup$

As @Biv pointed out in a comment, the only way to determine if something is secure is if you define secure. And even then, the answer is probably no, unless your definition is specific (see this answer for examples of security definitions in cryptography). It depends on how important is the data for you, which attacks you want to prevent and how much are you willing to invest to achieve your objective.

For this case, the problem in particular with symmetric encryption, such as AES, is that both sides need to have the same key. And if you have a channel to securely exchange a key, you have a channel to securely exchange a password. You can play around with public key encryption, and will find that certificates are required to reduce some of the most important risks.

So, if this is a one-time act of curiosity, I would say that the best approach is to rely on an application that offers end-to-end encryption. Signal, Telegram and Mega would be my initial thoughts (the first two for IM, the latter for cloud file storage), and definitely more reliable than an improvised scheme. If your curiosity persists, the description of the protocols of these applications can give you an idea of how the problem is solved in "real life".

$\endgroup$
2
votes
$\begingroup$

First: security through obscurity is not good! Don't do that. So either way zip, sms, is not secure unless you have in person agreed upon a key, Secondly, sharing a private key through obscurity is something that you don't do.

What you need is a way to

  1. Verify to the client that thay are "talking" to your server, simplest way, use a (* cert managers-- a third party whom verifies that your RSA pub key is valid ) RSA works for a client sending to a server only and is computationally expensive. So it should be used for the client side to server half of a key agreement.

    https://www.symantec.com/content/en/us/enterprise/faqs/b-prioritizing-trust-ca-security-best-practices_FAQ.en-us.pdf

  2. Generate a key that both parties can agree on (*ecdh key agreement, if possible use the m-383 curve) DO NOT share a full key through esa, this is a bad practice .key agreements mathmaticly derive a key on both sides. So the actual cypher key is never transmitted.

    https://ocw.mit.edu/courses/mathematics/18-704-seminar-in-algebra-and-number-theory-rational-points-on-elliptic-curves-fall-2004/projects/haraksingh.pdf

  3. Block cypher encrypt data: use a symmetric block encryption in a cipher mode; cypher modes prevent patterned correlation attacks that may be used to retrieve the keh, I would recommend AES, but if it is not in a cyphermode there have been successful attacks, these attacks belong to The correlation attack family, and are executed analytically. To successfully extract block keys

    http://css.csail.mit.edu/6.858/2015/projects/utsav-lisayz-skoppula.pdf

Lastly, this should be avoided, don't think about rolling your own crypto protocol, this is just bad news unless you fully understand how each protocol works, and even then those protocols are under close scrutiny by teams of tester and developers.

$\endgroup$
4
  • $\begingroup$ Thank you for the great information. I'd be remiss, however, if I didn't point out that this doesn't answer my question, which is how secure my solution is compared to sms and a password-protected zip file. I still have not found anything better that is simple and easy enough that certain clients of mine will actually use it. $\endgroup$ Commented Nov 16, 2017 at 17:03
  • $\begingroup$ Both zip and your approach and encrypted password zips offer AES which instantly makes them stronger then sms, but both solutions rely on obscurity so between zip and your solution, they both equally fail.Use an ssl. $\endgroup$ Commented Nov 17, 2017 at 19:11
  • $\begingroup$ Thanks. You're right. I will setup a one-time use web form for each information transfer. $\endgroup$ Commented Nov 18, 2017 at 17:08
  • $\begingroup$ Your welcome hope that helped. $\endgroup$ Commented Nov 21, 2017 at 16:59
0
votes
$\begingroup$

Basically, what I'm looking for is the easiest way to transfer login info in the most secure way possible that's still convenient to actually be used by real world clients unfamiliar with encryption and the more technical aspects of computers.

Let assume what are you trying to do is sending new user credentials to the users. As well lets assume general TLS/SSL use.

What is commonly done is sending an activation link (or one-time / time-limited password) and forcing the users to change their password on first login. This is clearly to comply with user level of laziness and conformity.

Using an off-channel (SMS / IM) and/or MFA (multi-factor authentication) seems used much more and IMHO far more secure.

How secure is a client-side javascript encrypter?

what concerns the algorithm - it is as good as it gets. depends how you want to use it. if you want to provide some confidentiality data in traffic, maybe plain TLS will to the same with less effort.

People have requested I define "secure." I thought people might ask that, so that's why I asked to compare to the security of SMS and password-protected ZIP file. Of course, nothing is ever truly secure. Phones can be tapped, people overhear, emails read, etc.

This is more question about level of information security - IMHO secure is when the gain is not worth the effort. You can do whatever you want and at the end someone "social-engeneer" a user, you are done anyway. So there are industrial standards and best practices you shall follow to keep you secure as much possible with reasonable effort.

One person cited that one'd be at the mercy of a third-party by using their code. In this case, I d/led it to my server and inspected it for malicious code. Anyone using my page could do the same.

Indeed. However - you are in the mercy all the time (even with your phone, email, SMS, ...). Though in this case you may trust the external libraries more than creating our own crypto or having some "inventive" way. If you come to the scripting libraries (Crypto-JS) If you really go after security of the scripts, I'd advice to host copies of the scripts on your server as well. It may prolong first loading times, but at least you can be sure abot content you are hosting.

There is an discussion about deceival of the SSL with external scripts - when seeing a "green lock" we tend to believe that the communication is secured and content is provided by the host we see the url on top of our browser. However - many scripts are provided by 3rd parties and its not always easy to ensure integrity of these scripts.

Why not give the info over the phone? That seems less secure, doesn't it?

eee.. it could work for 5 users.. but would you support unlimited number of clients?

I've found public-private key encryption is too difficult for people to understand. They'd get frustrated and go back to unencrypted email or a phone call.

at least have TLS/SSL securing the transport - that's easy to use

$\endgroup$
1
  • $\begingroup$ Actually, my use case is for the user to send me information, not the other way around, but I think your advice of using TLS still applies. I could simply setup an HTTPS-only website that has a web form for them to use. Then, provided that website sends me that information securely, this should solve my problem. $\endgroup$ Commented Nov 18, 2017 at 17:02
0
votes
$\begingroup$

Answering directly to the question,

var encrypted = CryptoJS.AES.encrypt(form.thetext.value, form.passkey.value);

To derive an encryption key from the password, CryptoJS.AES.encrypt uses EvpKDF (non-standard algorithm from OpenSSL) with 1 iteration. This is not secure at all unless the password already has very high entropy (which is often not the case), otherwise it can be easily brute forced. Proper password-based encryption should use at least PBKDF2 with high iteration count (or a better KDF such as Argon2, scrypt, etc).

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.