Channels ▼
RSS

Web Development

Getting Started with Google Apps and OAuth


Public-Key Encryption

The various tokens used in the protocol have to be digitally signed so that Google can assure that they came from a trusted source. So let's digress for a moment and talk about what that entails. Digital signing is based on public-key encryption, as opposed to secret-key encryption. With the latter, you would create an arbitrary encryption key that would be known to both you and whoever you were sending a secure message. You encipher the message with the key, and the receiver deciphers it with the same key. It's fast, elegant, and almost completely unworkable in the real world for one reason: How do you send the "secret" key to the person who's receiving the message? All is lost if the key is intercepted by an eavesdropper, who can then use it to read your message.

To the rescue comes the notion of public-key cryptography. Here, there are two keys (the "public" and the "private") involved. The two keys are generated at the same time, and as the names imply, you hide the private key away where nobody but you can access it, but can freely publish the public key anywhere you wish.

Any message that's enciphered by one of the keys (it doesn't matter which one), can only be deciphered by the other key. Imagine that you had published your public key on your website. If someone wants to send you a confidential message, they can encipher the message with your public key and send it to you. Since that message can only be deciphered with your private key, and since you're the only one who has that private key, you're the only one who can read the message.

Digital signing essentially flips that process over. If you encipher a message with your private key, then anybody can read it by using your public key to decipher the message. However, the very fact that the receiver could decipher the message effectively proves that it came from you, since only you could have enciphered it to begin with. (Just to head off the inevitable sniping, I'm actually simplifying here. A real "digital signature" is actually an enciphered secure "hash" of the message, but that's more detail than we need right now. Forget I ever said that.)

The one problem with digital signing as I've just described it, is that the person who's deciphering the message has to be sure that the public key that they think is yours is actually yours; otherwise, your signature could be faked by a "man in the middle." That is, you could sign the message and send it off into the cloud, where it was intercepted by a bad guy. The bad guy would use your public key to decipher the message, change it, and encipher it with their own private key, and send it off. If the actual recipient was tricked into thinking that the bad guy's public key was actually your public key, she'd think that the message had come from you.

So, how do I prove that a public key is actually mine? A trusted "address book" that contained everybody's public key, rather like the DNS database, would work; but in practice, that solution is impractical. What people actually do use is a "digital certificate," usually called a "cert." Think of a cert as a sort of credential, in the diplomatic sense. It's a letter that's signed by a trusted third party that certifies that the bearer is who he says he is. The letter has to have some sort of description of the person being certified, of course, to prevent it from being used by a bad guy.

A cert is effectively a letter that contains your name, URL, and public key. It is digitally signed by a trusted third party: a "certificate authority" or "CA." Since the CA's public key (used to validate the signature) is well known, it can't be forged. Browsers, for example, have the public keys for a dozen or so major CAs built into them, so they can verify certificates that are given to them by various servers. A public key that's identified by a certificate issued by a known, trusted CA is assumed to be authentic.

So, what does all this have to do with OAuth? Various tokens passed between the Consumer (your web app) and Service Provider (Google) are digitally signed using your private key. For Google to verify that you're who you say you are, you have to register the associated public key with Google. The process is straightforward: You create a public-key/private-key pair, purchase or otherwise create a digital certificate using the public key, then send that key to Google by "registering" the certificate. This is exactly the same certificate that you would install into Apache to support the HTTPS protocol, so if you've done that, you'll already have the private key and the certificate, which you can just send to Google. I've been using "RapidSSL" certificates, which are signed by a well-recognized CA (GeoTrust), and cost as little as $10/year from various resellers. It doesn't matter if the reseller is a fly-by-night operation running in somebody's closet, because the actual certificate is created by GeoTrust, not the organization you buy it from. Just go with whoever is cheapest.

If you've never created a certificate before, the easiest way to go about doing it is to use the OpenSSL package, which is installed on most Linux boxes and on the Mac as well. If you're running Windows, get a binary version by following one of the links on http://www.openssl.org/related/binaries.html.

Generally — for example, to use in Apache for HTTPS support — you would purchase a certificate from a CA. You don't need to do that for Google, but it's nonetheless instructive to look at the process. You typically purchase a Certificate in three steps: First, create a key using:

openssl genrsa -out myOrganization.key 2048

This request creates a file called "myOrganization.key" that holds an RSA key. Save that file in a really secure place, and make at least one copy of it on a CD or other physical medium. If you're purchasing a Certificate, you'll have to create a certificate signing request (CSR), as follows:

openssl req -new -key myOrganization.key -out myOrganization.csr

You'll be prompted for various fields, many of which can be blank (just type in a "." at the prompt to leave it blank). The important fields are:

  • (C) Country Name: US

  • (ST) State or Province Name: California (or whatever your state is).

  • (L) Locality Name: Berkeley (or whatever your city is).

  • (O) Organization Name: My Company Name, Inc.

  • (CN) Common Name: myDomain.com

The Common Name (CN) field is particularly important if you plan to use this cert for HTTPS, and it must exactly match the domain that you plan to secure. For example, if you intend to use https://secure.myDomain.com/... as a URL, the common name has to be secure.myDomain.com. If you specified a CN of myDomain.com, then you can use the certificate only to access https://myDomain.com. It won't work for www.myDomain.com, for example. You can, however, purchase a "wildcard" certificate that will work for all your subdomains (they usually cost more). In this case, use a CN of *.myDomain.com.

Once you have a CSR file, go to whatever site is selling the cert and follow their purchasing procedure. Eventually, you'll be asked for the CSR, and just cut and paste the contents of the CSR file into whatever text box the vendor supplies for that purpose (or upload the .CSR if they want you to do that). Once it's created, the vendor typically emails the certificate to one of the email addresses that's managed by your domain registrar — typically the Technical or Administrative Contact (or both). The fact that you receive the email proves (albeit weakly) that you own the domain.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 
Dr. Dobb's TV