Implementing Diffie Hellman Key Exchange on Javascript? - javascript

I'm a complete beginner in crypto. What I know about Diffie Hellman Key exchange is:
One Public key is generated and is world readable.
Sender and Reciever generate their own Private keys independent of each other or the public key
They mix their pvt keys with public key and send to each other
They mix the recieve d key with their respective pvt key and end up getting same key which is known by no one else.
They can now use any symmetric key crypto to encrypt and decrypt.
The question is: Is this computationally possible in javascript?

Yes, it is computationally possible (most algorithms are, given enough time and memory). However, I think you should read more into DH, because the above scheme isn't it. And if you have read into it, continue with ECDH because it will perform much better on Java Script.
Also note that implementing cryptography in Java Script has many pitfalls, especially if run within the browser, and even more so if it is run within the browser without TLS.

Related

Generate Mnemonic Phrase from window.crpyto.subtle.generateKey

I am developing and web based end to end encrypted chat website. For that I am generating private keys using the window.crypto.subtle.generateKey function provided in the web crypto api.
I want the user to remember or store a mnemonic phrase like we use in ethereum wallets instead of an encryption key.
Is there a way to generate the mnemonic phrase from the private key that is generated by the window.crypto.subtle.generateKey function or is there any other way I should go to implement this?
Thanks in advance
Is there a way to generate the mnemonic phrase from the private key
It's the other way around. A set of private keys can be determined from each mnemonic phrase - but you can't determine a mnemonic from a private key.
A widely-used standard is BIP-39. Even though it was first introduced as a Bitcoin Improvement Protocol, many Ethereum wallets use it too. You can find its JS implementation in this package for example.
Note: You're looking for functions mnemonicToSeed() and mnemonicToSeedSync(). Even though it might seem at the first look that entropyToMnemonic() translates private key to the phrase, it's not true - the entropy numbers are just positions of the words in the wordlist, not the private key bytes.
What you want, as you describe it, is to encode your private key into mnemonic words. Which you totally can, with the simplest example being: split up the key into chunks of n-bits, and match each chunk to a word list consisting of 2^n words.
Whether you actually want this for your overall purposes is a different question.
I'd also like to expand on Petr Hejda's answer, which at first confused me, but I now understand.
Petr is using the definition of "private key" in a different context than in the question. Petr is referring to "private keys" in terms of the bitcoin protocol, where the mnemonic is not used as an encoding for private keys, but to generate a seed which may then be used to generate any number of keys deterministically (BIP-0032), so that such generated keys can be re-generated when using the same seed, which in turn can be re-generated from the mnemonic. In this protocol, the mnemonic-to-seed is defined, but seed-to-mnemonic is not, because the protocol never does that. It only generates mnemonics from entropy, and then generate the seed from the mnemonic.
But in your case, you can simply feed it your "private key" (as you've defined it) as the "entropy" input in the entropyToMnemonic() function, and it will give you the mnemonic encoding of the "private key" that you wanted. You'll still have to decode it yourself though, as the BIP39 package doesn't have that functionality.

Performing AES Encryption is Ruby compared to Javascript

I am struggling at this one part of code where I need to decrypt AES on my server side (Ruby) from a client. I know all the information, but I am struggling with re-producing the encryption.
I am currently using CryptoJS from https://github.com/brix/crypto-js. I am not sure which version of AES it is using which might be my first problem.
An example of how I currently encrypt my data in Javascript is:
encodeURIComponent(CryptoJS.AES.encrypt("Message","Key").toString())
Right now I am currently using openssl and cgi in Ruby to try to decrypt. This is wrong and not working, but I wanted to show what I am trying as I believe it is close. I don't understand how the key is used in the encryption, but I am following the example I found here
require "openssl"
require "cgi"
cipher = OpenSSL::Cipher.new('AES-128-CBC')
cipher.encrypt
key = "Key"
iv = cipher.random_iv
encrypted = cipher.update("Message") + cipher.final
puts CGI::escape(encrypted.to_s)
I have just put "Message" and "Key" to not share my information, I am an amateur when it comes to security and cryptography, but I have done these things in lower level languages without problems. I believe the problem happens in two main areas
My lack of knowledge of how these high level languages work, and the libraries I am using
The strings are sometimes UTF-8 vs UTF-16 in these langauges, so passing the "Message" as a string might be causing problems
FULL EXAMPLE OF ENCRYPTION AND DECRYPTION IN JAVASCRIPT:
Encrypting and URL encoding with input 1:
encodeURIComponent(CryptoJS.AES.encrypt("1","Key").toString())
Result:
"U2FsdGVkX19Lp8ItQaO5h6Lj68sheHeYrIkJAfqt1Tw%3D"
Decoding URL and Decryption:
CryptoJS.AES.decrypt(decodeURIComponent("U2FsdGVkX19Lp8ItQaO5h6Lj68sheHeYrIkJAfqt1Tw%3D"), "Key").toString(CryptoJS.enc.Utf8)
Result:
"1"
At least one of your problems is noted by Artjom B noted in the comment above, and this is a frequent problem with trying to get crypto-js to interoperate with other libraries: crypto-js is not taking in a "Key" the way you are using it but instead a password. Passwords are not keys!!!
Internally, crypto-js uses a very poor algorithm for converting the password into a key. The algorithm is poor for two reasons: (1) it is based upon the insecure MD5, and (2) converting passwords to keys should be a slow process to deter brute force guessing of passwords. In crypto-js, the process is not slow.
To get you headed the right direction, do not call:
CryptoJS.AES.encrypt("Message","Password")
Instead, call
CryptoJS.AES.encrypt("Message", key, { iv: iv });
You might also need to explore padding to get it to interoperate with Ruby.

Web Crypto API: how to add passphrase to private key

We use window.crypto.subtle.generateKey to generate an RSA key pair.
How can we use the Web Crypto API to add a passphrase to the private key?
Keys generated with WebCrypto are not password-protected.
You could export the key and build a format that supports encryption, like pkcs8 in a PEM file, but to do this it would be needed to use an additional library.
I'm a bit late to the party, but isn't wrapKey() what you're looking for? It's on the same API and allows you to wrap the key up in a password-protected form, e.g. pkcs8.
#pedrofb is right. If you wanted to do this for better or worse PKCS8 is the right format, here is a link to code that can be used to create such a bag - https://github.com/PeculiarVentures/PKI.js/blob/5b9c35c154c48b232b45cc2a908c88e2f56a8447/src/PKCS8ShroudedKeyBag.js
You should probably also read this: http://unmitigatedrisk.com/?p=543 which describes some concepts related to key bags that are material.
You may also want to look into using webcrypto in a service worker and exposing an interface over PostMessage to get the operation to take place. This, combined with a non-exportable key, provides some protection from arbitrary use of the key, e.g the attacker can only do what the interface allows.

How to use public/private keys for short data without a symmetric cipher

I'd like to encrypt and decrypt data with private and public keys, respectively.
The data is between 1 and 32 bytes.
I do not want to use a symmetric cipher for the data - I want to use the keys on the data directly. (This is not normally done for performance reasons, but my data is very small.)
Is this possible and Where should I start?
I'd like to encrypt and decrypt data with private and public keys
Pretty much anyone who's worked with crypto will tell you that you write crypto at your own risk. Use the standard libraries, they're made with all the things that (if you are not aware of these techniques) leave your traffic unsecured.
That said, here's some Python libraries (but you can get this in most languages from PHP to Java or whatever floats your boat):
https://pypi.python.org/pypi/pycrypto
https://www.dlitz.net/software/pycrypto/
Crypto RSA in Python
https://pypi.python.org/pypi/PyECC
You'll see pycrypto because it's popular if you're looking to use RSA. Another package is PyECC which includes functionality for elliptic curve crypto. This is important if you're looking to reduce your key size or have less resources to devote to crypto, usually in mobile systems or something small. The difference in key sizes (link) can get ridiculous as the keys grow (for increased security)
Maybe keyczar is what you're looking for:
http://www.keyczar.org/

Signing and verifying text with key pairs using Javascript

Is there any library available (or well-written algorithm reference I could implement) that would allow me to sign a piece of text with a private key, preferably my existing SSH (RSA) or PGP key?
My goal is to write a bookmarklet to sign my blog posts, and provide another bookmarklet to allow others to verify them. I'm not trying to do any kind of secure communication. I just thought it might be neat to be able to store the public keys of others and use them to verify authorship automatically.
Maybe this one? PGP / GnuPG / OpenPGP Message Encryption in JavaScript
You may want to look into jCryption: http://www.jcryption.org/
It's made to encrypt forms using ajax, but it may be somewhere to get started.

Categories

Resources