Category Archives: Web

Introducing gmail-Crypt

I’m proud to introduce gmail-Crypt, my new project bringing OpenPGP to Gmail and Chrome via an extension. The project is Open Source, under a couple of different licenses because of the code coming from various sources.

In my experience, most of the existing options for OpenPGP/GPG/PGP are archaic and do not work well with how people use computers today. I think that we can create a simple experience with tight integration in the browser that can make encryption much more accessible.

The project is in very early stages right now, and the current version is definitely an alpha. However, I wanted to put a version out there. Please note that this is still being developed and may not yet be suitable for your super secret needs, as noted in the license there is NO WARRANTY of any sort associated with this software.

Install/Use

  • Click here to add the extension to chrome. It will ask you for permissions.
  • Open the Options page for the extension
  • You currently need to provide your own OpenPGP/PGP/GPG key. I hope to include key creation in a later version. Paste your private key into the box on the “my keys” options page. (You need to paste an armored version of your key. If you’re running linux try “man gpg” for more info)
  • Add keys for your friends (or your own public key) in the “friends keys” section of the options page.
  • Go to your gmail inbox. Compose an email to someone who’s key you’ve added. Click on the “encrypt me” in the upper right. *Note there is currently an issue where sometimes this will not display, try refreshing the page if this is the case.
  • If you receive an encrypted message, click on the “decrypt me” in the upper right of the page.

Send me mail!

You can send me encrypted mail if you want to test it out. sean @ colyer . name.

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.11 (GNU/Linux)

mQENBE61VRoBCAC9vxgdovC2KBqyhTzK+dAuT+5S2H5rjQY8gKBjW+ta2eSn/3Ts
Hjq0caeXR4mTualfbQbzv3k9ptDHd4wUNKftFegDxQTsExkrlluhB2asLfXcd7G+
Q3PF4M3R6tXdQo//ioW+zlvfK7fiQ7AaWLXfGBip60Z0OSABbRvRWB/TvouwMUtm
GzpT12LILPD19D7Gy6WpqQTyvEBhEBEp44x5jtFVSBKjJ+zsPmy6DvaBRtc27c87
HPwvlObybCE67EX793QyFsl4MVMYEkGSdprGuaT53pYJSMOKxpEo9M9EzsxZFhQV
QAhQQpao+aYKzdlvNjLOcJaTNADJ/ZywsjC1ABEBAAG0HlNlYW4gQ29seWVyIDxz
ZWFuQGNvbHllci5uYW1lPokBOAQTAQIAIgUCTrVVGgIbAwYLCQgHAwIGFQgCCQoL
BBYCAwECHgECF4AACgkQ5ymGNfSQhKrbQggAjbQ2SwtDki1H0RYBZKCNMMGf6CnX
r9gKTK6/0ipesUBTkptE5rXQK9X7dwDcybCY/EfUlSq/ww+auqs4byUlV5W78ARn
k4TUEiCkvO+gDY5xFzMHHF3vBTbFU3yA8moQKuZrNXkTcawjSSuiWk0asf7yerQf
Qfg5Bql2EUFiLGjFZEc63KZcu0GEDReu71fUVopzeSq4TeibniQwPkrrY0aJIBVS
iKZebl3wfh2hdqWu0Wf684Y5FrvRmTGWYjfG7Fde4DhpiZq5NkMExkO0kmwTBns2
Uv0LxCgGwQ8jY7M7OzmHjXGxjwqUkAiemvSgVMNA9BnydTrecCk3IiYLw7kBDQRO
tVUaAQgAzSkx8VEIq9z5h5CTCxdx9K3aRInUKB4PUTaAcYYF8GbdmBPMQUdK+shx
uzllqf16bCtrDHvW/c27msyslp8a/S65HjtmpTZ8EudchAKOR+uLk1+tVRBcxYlb
nSfELcJcxjpLr3Y1uH202EAzKn1apmEFwLD+PhB+VqagKME2SIfNc/ArISXXsOgb
+r8BIIZD8aU0gAtvagpnnSM2LAQP5Q3pCzZkrsBpfNq30tMbn4Yynk/wEg5UA1fn
UVAxJjYtENKWxy+enmJHNM6a13nmNQFSXHG1ss0hSWqMoWPTNAO8fZH9/M/v25Ys
hs99D/tdZDawttAdQAsiqKR8DasgEQARAQABiQEfBBgBAgAJBQJOtVUaAhsMAAoJ
EOcphjX0kISqxUEH/i2wSbM746gKB5qYAuCWCCqf8yzk8Rkc1Cu00nS5wT+V7Dyt
BCZvBuDKkNSgtRi+lALPmOARzJoIhwrBIG9ERf9vgDeBonEyMKYkYWOisMR7Qwh6
r35knJJZ4RZVrk7VVRJcEws5Li77IOOR6RXNFS2plwq1LIMAhlt+ocVIEQLBhUjk
N1Eksx0M6JCOy0pMm6srd4VoFZW6tVzD/vXPzcZLuy3Yfy6cfomWE93xpkbA9KOO
+uqtgxDYf2yg3PTkGIrqNDxE6yVkGBv2+XQ1TQDNwKMDpvPWHJIfvXHPd0NkpANm
Zm+3euyYoSme/3eKjpWfbhZOtmSyfM7Qo7WCbZk=
=8Sql
-----END PGP PUBLIC KEY BLOCK-----

Developer Details

jsOpenPGP

I’ve decided to dub the JavaScript OpenPGP library for this project jsOpenPGP. It aims to be an independent library that can be used in other projects as the library to provide OpenPGP encryption. Currently it supports RSA/AES/SHA/CAST5 encryption/decryption. It does not yet do message signing or key creation.

By combining the work by Herbert Hanewinkel and Tom Wu, we are able to create a powerful library. Both of these libraries had to be modified to work together, and the OpenPGP code was mostly re-written to provide a more object oriented approach and some code simplifying that I believe will make the project easier to build on.

Architecture

The project takes advantage of the “walled garden” approach to extensions. Through the use of a content script, there are changes made on the gmail page, which also interacts with a background page that serves as the middleman between the extension backend and the gmail front end. This is necessary because we want to store key information in the context of the extension, and this allows a certain level of protection between the gmail page and the key details in the extension. Google provides a good overview of this architecture.

Related Works

  • GPGTools is working on using a JavaScript implementation of OpenPGP for a mobile app.
  • Thinkst has released an extension that performs a very similar feature. However, rather than using a Javascript implementation, it uses a user-installed GPG binary on the local filesystem.
  • FireGPG used to be very similar. It runs only in FireFox. It has stopped supporting Gmail

Todo

There is a lot of work still to do. Things I’d like to accomplish include: Key creation, key signing, find a good draft uploading solution, further integration with the browser, bugfixes. Check out the latest source for most recent details.

I would love help, head on over to the project page if you can help out!

Newsgraph, or the News You Need to Know

Newsgraph: prometheusx.dyndns.org

You need Firefox or Chrome to properly see the page. Other HTML5 browsers should be able to support it (IE9, Safari), but I have been unable to test them.

I realized recently that it’s very easy to lose track of big news items. Perhaps you’ve gone on vacation or have just been really busy, but the stories that are on the collective conscience for the day can sometimes pass you by.

Inspiration
As mentioned, I wanted to find a way to graph news over time. I find that it is easy to fall out of the loop with news, particularly when away for vacation or whatever reason. I wanted a way to quickly see the important news that you have missed.

A long time ago I had seen an interesting visualization of news but was unable to find it again until I had started this project: newsmap.jp. It provides a detailed view of the news that is happening right now. Despite using Flash, the interface is much more solid than the one I have put together. My design was certainly influenced by seeing this.

Algorithm
The page is populated via Google News stories. Google News provides RSS feeds, free for non-commercial purposes (so no, I don’t plan on making money from this). The various RSS feeds are regularly polled and update the stories as needed.

The popularity of a given article is determined by the associated number of articles for the given story. I don’t think this is the best metric because I think some stories are more likely to generate articles for the sake of SEO and ad-revenue. The SEO optimization of journalism is a pretty broad concern for new media, but it tends to influence the page more than I would like. I would like to use other means, perhaps number of commenters for different stories or pageviews. Obviously, these would not be perfect either. By using something like what your friends are reading would be interesting as well, but the social aspect would make the page completely different.

The page is essentially the Top 40 of news.

Technical Challenges
Determining the appropriate text size was difficult, because of the wide range of possible shapes. I needed fonts that were readable for the wide range of popularity (some articles are orders of magnitude more popular than others). Additionally, once the font was determined for popularity, it needed to be adjusted if words were going to creep into the surrounding boxes.

The javascript below outlines how I dealt with the font size and the wrapping issue. Basically, my javascript will loop through all the words and attempt to fit them on a line until that line is full, if adding a word exceeds the width of the rectangle, remove the last added word and insert the given words. If there is only one word and it exceeds the width of the rectangle, shrink the font by an appropriate amount so that it will fit and then insert the given words.

   var fontSize = (10+numArticles/800);
function textBreak(context, text, x, y, fontSize, lineHeight, maxWidth, maxHeight){
   words = text.split(' ');
   var lowCount = 0;
   var lines = 0;
   for(var n = 1; n < words.length+1; n++){
      context.font = "bold " + fontSize + "px " + font;
      var line = words.slice(lowCount,n).join(' ');
      var width = context.measureText(line).width;
      if(width+3 > maxWidth){
         if(n > lowCount+1){
            n--;
            }
         else{
            var fontDiff = (width+3)/maxWidth;
            context.font = "bold " + fontSize/fontDiff + "px " + font;
         }
         context.fillText(words.slice(lowCount,n).join(' '), 3+x, y+ lineHeight*lines);
         lines++;
         lowCount = n;
      }
   }
   if(lowCount < words.length){
   context.fillText(words.slice(lowCount,words.length).join(' '), 3+x, y+ lineHeight*lines);
   }
}

The other issue that was a bit difficult to figure out was how to link to the articles. You cannot use a href for different sections of the canvas. You could wrap the entire canvas with one, but then you obviously couldn’t get to individual articles. I ended up creating a mouseup function that would look up links in a dictionary for given X,Y coordinates. Since articles are all aligned on the X-axis for the days of the week when drawing articles, I could populate an object that would map the starting X-value for a given day of the week to the starting Y-values for the stories on that day. This provided an efficient solution that covers the entire area of the canvas and maps them to the necessary stories.
The method for adding values to this object is:

function addLink(xStart, yStart, link){
if(linkMap[xStart] == undefined){
linkMap[xStart] = {};
}
linkMap[xStart][yStart] = link;
}

The javascript code can all be viewed simply by viewing the source of the page. I just chose to highlight some of the more challenging issues here.

Design Iterations
One of the things I wanted to do with this project was get a little background with the HTML5 canvas object. I originally had many canvases, but that ended up treating them more like div’s and was not the approach I wanted. Canvas objects are quite easy to draw basic shapes with, such as a bunch of interacting rectangles.

The attached screenshots demonstrate some of the design process. Originally, I had laid out the news stories as a series of canvas objects, that I decided size on by a fixed multiplcation depending on the number of articles for the story. The layout was monochromatic and would scroll down fairly far. The second image shows the majority of the layout for the Newsgraph, the day widths are determined by total amount of news for a given day and the total area for a story was indicative of the total number of stories. The last two screen shots show the present state of the application, you can click on different topics and see the most popular stories from the past week for that topic, with older stories fading to black. The final screenshot shows the “all” category of news that makes up the general page.

I hope somebody finds this useful, I did it primarily for my own satisfaction and as an interesting way to visualize news over time. Please send me any questions/comments/concerns.

Appendix
Apologies if the site is slow to load or shows issues. Unfortunately, my web-hosting is none too accepting of Ruby on Rails (webhostingbuzz.com). This left me with a few options: use a more static web coding or host it myself. Since I wrote this as a proof of concept more than anything else, I decided rather than re-writing the RoR application, I would just host it myself. However, the rails application does very little, it serves up a static webpage and then provides an XML feed of the news. It could have been relatively easily re-created in a different language.