Generate Mnemonic Phrase from window.crpyto.subtle.generateKey - javascript

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.

Related

Encrypting and decrypting data on client side using cryptojs

I am working on chrome extension to save some user data to local storage. I encode data with crypto-js.
However I am facing one minor issue/dilemma - if I encode user data using secret key abc123 I get something like this 2FsdGVkX19v0LNG0FKFv1SxAQj4AqdNvWWMGyi9yVI=. However if I decrypt it using another secret key like abc I get empty string. Only the correct secret key return non empty string.
So my question how do I need to encode data, if decoding with wrong key it would still return some string? Is there some configuration for this or different encoding?
If I am a hacker and I am using brute force to crack data it looks pretty obvious, what secret key user is using to encode data.
Fidller to fiddle with configuration.
Since you're using Crypto.js you're limited to popular and battle-tested algorithms. Let's say that you're using AES-256-CBC with a key derived from a password ("abc123").
If you encrypt something that a human uses then it likely has low entropy and therefore some structure to it. Think about some JSON string that you're encrypting. If the attacker tries to decrypt the ciphertext with some random key they might get random bytes. If they know they have to get JSON back, they have an oracle whether the decryption worked. They try again with a different key and get different random bytes. They repeat this until they find a plaintext that has a valid JSON structure. Even when they don't know that it is JSON, they might utilize statistical methods in order to deduce whether they got the right key.
You might need to use gzip before encryption in order to make that deduction harder but then the attacker might just incorporate an ungzip procedure in their bruteforcer and just do the statistical analysis.
AES is a block cipher where changing a single bit in the key changes roughly half the bits in the ciphertext with a constant plaintext. That means the attacker will not be able to see that they are getting closer to the correct key. They will have to try all of them.
The usual way of making it harder for an attacker is to increase the work factor. Crypto.js uses by default EVP_bytestokey with a single iteration of a MD5 hash of the password in order to produce the key. This operation is quite fast. You could change that to something like PBKDF2 with a million iterations but today's computers are so fast that this doesn't solve your problem...
The main issue is that your password is too short. "abc123" is a password that can be bruteforced in milliseconds when using Crypto.js defaults (1xMD5) and maybe minutes when using PBKDF2 with a million iterations. Adding a single character to a password multiplies the bruteforce effort by at least 50 (depending on class: upper, lower, digits, special).
Now you can calculate how long your password should be in order interfere with an attacker that corresponds to your risk appetite.
Note that just having encryption doesn't solve all your problems. Usually, the threat still exists.
You only can decrypt your data with the encryption key.
I personally wouldn't encrypt data in a frontend application.
Maybe you should have a look at the documentation:
https://cryptojs.gitbook.io/docs/

Tensorflow.js is there a list of all the identifiers

I'm a bit new to Tensorflow, I started to user Tensorflow.js for a project but I'm running across a few issues : in many field (s.a. activation, optimizer, loss, metrics, etc.) we can use a string to reference an object that fit our need, for some we can use a direct object reference (s.a. tf.losses.sigmoidCrossEntropy) and I found this version way easier because I can't find the identifier I need, this must be stored somewhere but where is it ? Is there a list of all the possible identifier ? (I searched stack, google and quant but I can't find anything...)
In advance, thank you !
This is not exactly "documentation", and it's obviously not very easy to find, but at least it will solve your concrete problem now: https://github.com/tensorflow/tfjs/blob/f111dc03a87ab7664688011812beba4691bae455/tfjs-layers/src/keras_format/loss_config.ts#L16
Similarly, for other string identifiers (activations, metrics, constraints, initializers, and regularizers), see the neighboring files under https://github.com/tensorflow/tfjs/tree/master/tfjs-layers/src/keras_format.
In general these should match the string identifiers used for Python Keras. For instance, https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy shows name='categorical_crossentropy'. However, the TFJS implementations may not be up to date with the Python Keras ones (in particular, any new losses etc. added in the last year or two on the Python side are probably not implemented in TFJS yet).
Tensorflow.js Layers follows the Keras API, so you can find all the string identifiers in the docs at https://keras.io. For instance, https://keras.io/activations/ lists 'softmax', 'elu', etc.
sebastian-speitel's answer is also correct that there is generally a 1:1 correspondence between the class/function names shown in the TF.js API docs and the string representations.
One wrinkle: Keras uses snake_case string identifiers such as hard_sigmoid, but in TF.js we require lowerCamelCase, e.g. hardSigmoid. (Most identifiers are a single word, in which case there's no difference).
We should certainly document this better in the TF.js API docs. Tracking at https://github.com/tensorflow/tfjs/issues/1315.
Under losses in the official document you can find all possible loss-functions. The same for the other ones.
I'm not 100% certain, but every one of them should be able to be used as string reference.

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.

Implementing Diffie Hellman Key Exchange on 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.

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