Encrypting JSON in Google Gears Workerpool - javascript

I need to encrypt JSON (stringified) data in a Google Gears Workerpool. So far, any implementation I tried either makes the Gears Workerpool bug out, or gives me unwanted encrypted strings.
For example: DES encryption (can't post URL due to account restrictions)
This works brilliantly for most applications, except after encrypting my JSON, it adds linebreaks where I don't want them. Decrypting only results in a broken string that can't be worked with.
For example: AES encryption (can't post URL due to account restrictions)
This also works, in theory, but once I paste the source code into my Workerpool javascript file, the Gears Workerpool gives a vague error message. Upon removing the script from said Workerpool, it all works again.
What I am looking for:
A very simple encryption implementation in javascript, that uses a key to encrypt and decrypt data. Using a key (or password, if you will) is important. Additionally, encrypting a typical JSON string and decrypting that same string should result in perfect results.
It is all pretty important, as it involves medical data for offline usage. So if you have any other ideas on how to safely store JSON data in the Google Gears (sqlite) database, I'm all ears!

Maybe this is not answer directly to your question but Dojo offline have something like ENCRYPT and DECRYPT in Dojo SQL syntax this can be helpful. Usage of this can be found here

I found the answer through a friendly colleague. First I apply the DES encryption, after which I apply BASE64 encoding. This string is then saved into the database.
Decrypting in reverse also works, but leads to another troubling issue. Apparently 2 out of 3 times my JSON is suddenly invalid, upon trying to parse it using javascript's EVAL function (or JSON's JSON.parse method) it returns an exception: Illegal character.
I'll try to fix that or otherwise open up a new question ;)
Cheers!

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/

Reveal JavaScript decryption algorithm

I have been trying to understand how exchange rates are updated real-time on this website. With a quick look at the 'network' tab on developer tools, it became clear that website is getting responses periodically from this url. The problem is that the response text from the requests consist of sequences of random letters and numbers. It seems that actual content is encrypted and since exchange rates are displayed on client side, response data should be somehow decrypted with JavaScript on front end (I think).
So, my question is, what are some hints to explore JavaScript decryption algorithm, since all 'js' files are minified and variable names are just letters? What kind of tools and practices could you use to solve this kind problems?
Any suggestion or help on this matter would be very much appreciated.
The source code (not minfied) can be seen here. You will notice that it uses a function rc4decrypt to decrypt the data. rc4decrypt is defined as:
function rc4decrypt (a){
return rc4(key,hexDecode(a))
};
where key is a global (window) variable. Further steps should be easy.
(Please be aware of any legal implications of your actions).

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.

Checking GPG signatures in Javascript

There is already a solution for extracting public keys and encrypting messages in JavaScript, but I cannot figure out how to decrypt messages or check signatures. Any ideas?
From what I can see, there is already a function for actually decrypting the message, now it's just a matter of extracting a private key so messages can be signed. Correct me if I'm wrong, but it looks like step 1 is to decrypt the secret key string, then get the MPI (multi-precision integer), then separate it into the prime numbers and decryptor, which can be passed to the decryption function.
I wrote a generic GPG/PGP NPAPI library for use in the browser that has public methods for most everything, including decryption and verification.
The plugin source is located here: https://github.com/kylehuff/webpg-npapi
The plugin is currently in use in the WebPG extension for chrome, located here: https://chrome.google.com/webstore/detail/hhaopbphlojhnmbomffjcbnllcenbnih
And the extensions source is locate here: https://github.com/kylehuff/webpg-chrome
Both are cross-platform for Windows, Linux and OSX.
There's a chrome extension https://chrome.google.com/webstore/detail/pinhikmcljjkhnpjmpfkhjgiaacajajm though I'm not sure if it works on Windows yet -- I'm trying it out myself right now.

How to simply encode and decode a string variable

I need to simply encode a string variable (my api key) so that is not easily readable by human eyes, I need it to easily decode back to exactly the same initial string. What is the standard practical and fast (less computing on the user side) way to do this?
Many thanks in advance!
If it doesn't have to be super-secure, Base64 encoding is always handy:
http://www.webtoolkit.info/javascript-base64.html
Everything you can do to obfuscate information on the client implies that you include the code for de-obfuscation right next to it.
So… apart from adding one extra step for your program (and the hypothetical attacker), you gain nothing. Well, not much anyway.
If your API key is secret, keep it on the server and let the server do the work through HTTP requests.
You could try a Javascript Obfuscator to either encode your whole script or parts. Not an absolute solution but a start to protecting your code.
you could use a 3rd party base64 encoder library: http://ostermiller.org/utils/Base64.html
Is this secret information or not?
If it is secret, you need a real encryption library and some deep thinking too make sure your secret is kept secret. I would seriously consider never sending any secret to the browser.
If this isn't secret and you just need need to send this over the URL without it getting borked then escape()/unescape() are what you are looking for.

Categories

Resources