Checking GPG signatures in Javascript - 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.

Related

Javascript file blocked by a corporate firewall

We have a site where we're using zxcvbn by Dropbox to inform users of their password strength, however, we've been getting occasional reports that it doesn't work.
Turns out that these users (reasonably rare) are accessing our website from their workplace which has a strict corporate firewall policy, because the js file contains swearwords and NSFW words (to mark the password as insecure if it contains these commonly used words), the whole JS file is being blocked from loading.
The rest of our site loads fine, including other JS files.
How could we encrypt or minify this js file to a point where it didn't get blocked for having "bad" words in the request, but be successfully decrypted at the client side to actually do it's job and detect unsafe passwords?
This JS Fiddle will (sort of) demonstrate the problem: https://jsfiddle.net/0cgap96m/3/
<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js" integrity="sha512-TZlMGFY9xKj38t/5m2FzJ+RM/aD5alMHDe26p0mYUMoCF5G7ibfHUQILq0qQPV3wlsnCwL+TPRNK4vIWGLOkUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="test">
</div>
window.onload = function(){
var name = prompt("Put in a fake password to test?");
var passwordStrength = zxcvbn(name);
document.getElementById('test').innerHTML = JSON.stringify(passwordStrength);
};
That should work fine normally - now try blocking https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js using an adblocker or something, and it'll obviously start failing. This is essentially what's happening for the users, but it's blocked by their corporate firewall rather than a local adblocker.
To confound the filter, you can try substituting the literal characters with JavaScript's syntax for the unicode representation of those characters.
This works even with identifiers!
var f\u006F\u006F = 'b\u0061\u0072';
console.log(foo); // outputs: bar
You could download the built js file and alter the passwords list, to split up the string in between the NSFW words. Then your copy of the library instead.
In zxcvbn.js the insecure words are defined like this (shortened here for this example)
var frequency_lists;frequency_lists=
{passwords:"123456,password,eatshit,goodluck,starcraft"}
So, by doing this:
var frequency_lists;frequency_lists=
{passwords:"123456,password,eatsh" + "it,goodluck,starcraft"}
a firewall scanning for swear words shouldn't recognize that as a swear anymore.
EDIT:
I might suggest a PR to their repo to have their code build with this format might be a better solution with the additional benefit of solving the issue for anyone else using this library, as well as allowing you to update to newer versions. But from quickly looking at the github, I see you'd need to be familiar with coffeescript + python. The original solution is much quicker and doesn't require knowledge in other languages.
how about a simple error handling client-side and a proper validation server-side?
Actually, you don't even need the validation, but if the typed/submitted password is sent to evaluation on server-side when client-side is not available may cover all the bases you need.
And if you need validation, well you should have it server-side, too, anyway, right?

PhoneGap plugin: fastest way to transfer JSON data to native

I have been working on a PhoneGap plugin to enable WebGL, intended for publishing HTML5 games to mobile. It's called WebGLGap. However, PhoneGap's way of calling plugin code (via exec) typically involves stringifying all the parameters to JSON, then parsing it on the other side again. According to this question, this has not changed even in PhoneGap 2.2 which was advertised as having a faster bridge. For something like WebGL, this is absolutely untenable and kills performance (<10 FPS) even for simple demos. This is because in many cases, especially 2D games, every frame must transmit a large block of JSON data representing all the WebGL commands to run. This includes all vertex data - imagine a huge string of "0.959455, 0.959595, 0.588575, 0.585858..." etc every frame.
Obviously stringifying and parsing is an unnecessary and inefficient step, but I'm struggling to find a way to pass the JSON data from JS to native which avoids that. Ideally this should work on both Android and iOS, but I'm happy to stick to an Android-only solution for now. Does anyone have any ideas about the most efficient way to do this?
Linkedin use Web Sockets for their iPad app. Might be worth looking into: http://engineering.linkedin.com/mobile/linkedin-ipad-nativeweb-messaging-bridge-and-websockets
Some of the benefits that you're looking for
WebSockets can communicate asynchronously from JavaScript to native.
WebSockets don't have a payload limit
WebSockets don't require us to encode our JSON strings as URL parameters
WebSockets should be faster than URL scheme navigation
Addressing performance
Looking at CordovaPlugin.java, as you mentioned, everything is a String:
public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
JSONArray args = new JSONArray(rawArgs);
return execute(action, args, callbackContext);
}
If, for example, the conversion from String to JSONArray is the only bottleneck, then you could override this method in your plugin and perform your own deserialization. It's a small performance improvement, but it might be worth investigating.
Creating an alternate bridge
As for creating an alternative bridge, that's trickier. I don't know much about Cordova / PhoneGap, but from what research I've gathered, Cordova exposes a specific Javascript interface via addJavascriptInterface. If you could implement your own NativetoJSMessageQueue, you might be able to wire it all together.
EDIT
After conducting a bit more research, I can provide a bit more direction. The really relevant part of the NativetoJSMessageQueue is the various BridgeModes it implements (see line 92). You could look at the other bridge modes as an example.
Unfortunately, the NativetoJSMessageQueue has exactly four bridge modes registered; assuming that you could implement your own bridge mode, you would still need to some how register it as a new mode for the NativetoJSMessageQueue.
I'm not sure what exactly you want to do but I notice that in your project you are converting the JSON to String and then you will pass it through the PhoneGap plugin , convert it to JSON and then convert it to Matrix!
what if you keep your data in a string and convert the string straight to Matrix?
this way you can skip the converting to and from JSON part
On android, you can try to use the addJavascriptInterface (link to WebView's documentation) method of the WebView to "inject Java objects into the WebView", which is the approach PhoneGap uses to add the apis for geolocation, filesystem, etc.
I guess this will be faster than using the plugin approach (didn't test this yet).
Check the code of the PhoneGapView, which extends WebView:
https://github.com/phonegap/phonegap/blob/3c7324ea8b3944b6e5d3d91e9e328c9c3939464b/android/framework/src/com/phonegap/PhoneGapView.java#L42
UPDATE
After all, this only works for simple types such as int or String, like you said in a comment below.
Passing a JavaScript object using addJavascriptInterface() on Android
Trying to do otherwise will result in exceptions from within the android.webkit.WebViewCore and android.webkit.JWebCoreJavaBridge classes.
UPDATE 2
Well, the best code you'll achieve using this approach will be something like this
(from https://github.com/commonsguy/cw-advandroid/blob/master/WebView/GeoWeb1/src/com/commonsware/android/geoweb/GeoWebOne.java#L80):
public String getLocation() throws JSONException {
Location loc=myLocationManager.getLastKnownLocation(PROVIDER);
if (loc==null) {
return(null);
}
JSONObject json=new JSONObject();
json.put("lat", loc.getLatitude());
json.put("lon", loc.getLongitude());
return(json.toString());
}
and most likely, all parameters should be string'fied (or JSON'fied...)
This might help you if you have a performance hit when triying to create strings from javascript side: http://www.javascripture.com/ArrayBuffer
I've read about encoding data in png. Here is the original article: http://cg.alexandra.dk/2012/11/26/webgl-tutorial-optimizing-data-transfer-for-webgl-applications/
Might be useful.
Given that json is very inefficient, you may gain a lot of performance if you take this route:
server side:
data model -> protobuf (build() to binary) -> encode base64 (binary to string) -> add as one json field or payload (best is to pass binary blob as a payload, but I'm not sure if PhoneGap allow this)
client side:
decode from base64 (string to binary) -> protobuf (parse from binary) -> use the protobuf objects directly as deep as you can in your code - it's extremely efficient data model

Determine if rar file is password protected

I'd like to be able to determine if the beginning portion (ideally first MB or so) of a file is of a password protected rar file. I don't just need to know if it's a rar file, I need to ensure that the file is password protected.
Is this possible? I know that the rar format is a proprietary format, but is this possible?
Edit:
I'd like to do this by examining the file's content, with either javascript or perl. It should not have access to the rar library.
Edit2:
With at least some consistency so far, I have been able to determine that the 10th byte appears to be always set to zero if no encryption is enabled. I haven't done enough testing yet to confirm this works reliably yet, but nonetheless, that is the result I am seeing.
My experiments gave me the following subroutine:
sub is_rarfile_protected {
my ($rar_filename) = #_;
open my $rar_fh, '<', $rar_filename or die $!, "\n";
sysread $rar_fh, my $mark, 25;
return ord (substr $mark, -1) & 0b100;
}
... which works for me so far.
Sadly, I don't have Rar installed, so I cannot check whether it'll work on all the password-encrypted rar-files (including multi-volumes, etc.) or not.
You could always try this
For those who can't perlmonks:
Re: Determine if a file is password protected
by rubasov:
If you don't want to implement the file format specific test for each of your extensions, then you can peek in the randomness of your data. Any well designed encryption scheme will result random looking encrypted data (to resist statistical analysis). But if the encryption is poorly designed this won't be much help for you.
Beware that this approach has serious caveats: if your data can be real/pseudo random or compressed data, then it will also look like than a pile of random bits, so for example you won't be able to distinguish between a simple and an encrypted rar/zip file. (And don't forget that simple looking document formats can use compression internally.)
For the concrete implementation search for the chi square test on CPAN (I haven't looked but I'm almost sure you'll find some implementation) and try to experiment with it whether it can be good enough for your purpose.

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.

Encrypting JSON in Google Gears Workerpool

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!

Categories

Resources