Image of the glider from the Game of Life by John Conway
Skip to content

Alphabet Book

image

Our family has been tasked with drawing a picture for each letter of the alphabet in an alphabet book for my soon-to-be-born niece. The letter ‘d’ was available, so it was obvious to me what should be drawn. I know when she starts flipping through the pages of the book, she will love this page the best.

PGP/MIME Versus S/MIME

I’m going to try to keep this post short (many of my regular readers will know how long winded I can be). However, with my recent post of setting up Mutt to support both PGP/MIME and S/MIME, based on the account I’m using, I figure a followup post on their similarities and differences might be in order. So, here it goes:

PGP/MIME

  1. Uses the OpenPGP RFCs and standards.
  2. The “signature.asc” detached signature is in plain text.
  3. Flexibility in algorithm choice for encryption, signing and compression.
  4. Relies on a distributed trust model.
  5. Not as widely deployed in MUAs as S/MIME.
  6. Public key must be distributed separately from the signature.
  7. Trivial to integrate with webmail providers.
  8. Can only be used with signing documents.
  9. An expiration date does not need to be set on the public key.
  10. Free.

S/MIME

  1. Based on a number of RFCs and standards.
  2. The “smime.p7s” detached signature is in a binary format.
  3. Generally, the Certificate Authority (CA) chooses the algorithm and key size.
  4. Relies on a centralized trust model.
  5. More widely deployed than PGP/MIME
  6. Public certificate distributed in each detached signature.
  7. Difficult to integrate with webmail providers.
  8. Can be used for both signatures and encryption.
  9. Generally, the public certificate expires once per year.
  10. Some CAs provide certs free for personal use, but most if not all CAs charge for professional use. As low as $20 per year, depending on the CA.

This isn’t an exhaustive list, but it’s pretty good. I’ve tried to keep any bias out of the list, and just mention the facts. Really, I get a kick out of using both, so meh. But, if I were forced to choose, I would choose the distributed OpenPGP model for signatures.

The biggest reason for this choice actually doesn’t even use PGP/MIME, thus the reason it’s not listed. That reason is I can set preferences in my key as to what must be used when encrypting documents to me. Thus, I can force you to send me a 2048 RSA encrypted document. With S/MIME, which can handle encryption, no such preferences exist, which means that there is nothing from stopping you sending me a 40-bit RSA encrypted document. I think you can see the security problem here.

Another problem I see with S/MIME is the reliance on a centralized authority. Essentially, you can trust I signed my mail with S/MIME, because my certificate is signed by DigiNotar and we all trust DigiNotar. Oh, wait. While the issuance of fraudulent public keys is a reality, the probability is much less likely, due to the distributed Web of Trust. Of course, this means there is a fair amount of homework that you must do in verifying that the key is legit, and that confidential information can be trusted with that key, but it is possible to make such assumptions.

Lastly, S/MIME is rather trivial to maintain. You pay a CA for a certificate, and you install the certificate in your mail client, and you’re ready to go. OpenPGP and PGP/MIME isn’t so trivial. You must generate your own keys, generally with PGP or GnuPG, and know the difference between your private and public keys. Then, you must install a plugin or extension into your MUA, which all don’t support, and configure that plugin to work with your keys. Then you must distribute your public key to friends and family, as well as keyservers, so others can grab a copy. But they can’t trust your data, until they meet up with you and do a keysigning, which means you must then redistribute the public key after their signature has been applied. In both cases, however, you can’t encrypt data to people unless you have their public key or certificate.

Both are internet standards, and both are fairly widely deployed. Unfortunately, there is work on your end that must be done on setting it up, and maintaining it, whether it’s a yearly cost or attending keysigning parties. As a result, it’s not as widely used in practice as much as it could be. I’ve made it a personal philosophy that I won’t send mail unless it’s cryptographically signed. This is true both personally and professionally. I would love it if my family and friends took the steps necessary to verify the signature, but it just isn’t going to happen. End-to-end security with email seems to have just too many speed bumps that people are willing to handle. That won’t stop me though.

Anyway, I hope this was at least somewhat informative.

Setting Up Mutt With S/MIME And PGP/MIME

If you have two accounts that you use with Mutt, and one of them you would like to use your OpenPGP key for signing mail (PGP/MIME), and the other you would like to use an OpenSSL certificate for doing the same (S/MIME), then this post is for you. Before beginning, however, you need to have the development version of Mutt (1.5.x) and it needs to have S/MIME support compiled in (which is the default for Debian/Ubuntu).

In my “~/.muttrc”, I have my accounts separated into two files, so I can set specific options for each account that don’t affect the other. As a result, here is the relevant parts of my ~/.muttrc:

# ~/.muttrc
folder-hook "personal.mail.tld" "source ~/.mutt/personal.rc"
folder-hook "work.mail.tld" "source ~/.mutt/work.rc"
source ~/.mutt/personal.rc # use this as the default account when Mutt executes

So, I have two accounts: “personal.mail.tld” and “work.mail.tld” (those are actual URLs to your accounts, whether they be GMail, Yahoo!, or whatever. Change as necessary). So, let’s take a loot at the relevant parts of “~/.mutt/personal.rc” and “~/.mutt/work.rc”:

# ~/.mutt/personal.rc
source ~/.mutt/gpg.rc
# ~/.mutt/work.rc
source ~/.mutt/smime.rc

Obviously, I’m sourcing external files. The personal account sources the gpg.rc config, while the work account sources the smime.rc config. Both of these configs can be found as example files in “/etc/Muttrc.d/” on Debian. From there, I made my edits.

Obviously, for both configs, I will have needed to setup cryptographic keys. For GnuPG, I will need to generate and save off my public key pair. There is a wealth of documentation on the internet that discusses this, so I won’t cover that here. I’ll just assume you have it created already.

For S/MIME, you will need to generate an OpenSSL certificate, signed by a centralized certificate authority. For myself, I chose Comodo. It was easy and quick. I had my SSL cert in less than 5 minutes, and it’s good for a full year, and it was free.

Once you get the email about the certificate, when you click the link to open it in your browser, it will install your certificate in the browser. No big deal. Just navigate to the certificate using your browser’s menu, and backup the certificate (both the private and public keys) to some local directory on your machine. It should have “.p12″ as its extension. Then, copy the certificate to the machine that will be running Mutt.

On the machine that you will be running Mutt from, you will need to issue a few commands to get your environment setup correctly before you can start using the certificate. You will need OpenSSL installed before you can begin:

$ smime_keys init

This should create “~/.smime/”, “~/.smime/certificates/” and “~/.smime/keys/”. After which, you will need to copy “ca-bundle.crt” to “~/.smime/”. “ca-bundle.crt” is provided by a number of packages, and you can find it on the internet should it not already be installed. After that is copied, type the following:

$ smime_keys add_p12 /path/to/your-backed-up-cert.p12

You will be asked for the passphrase for the private key in the .p12 file, as well as a new passphrase for encrypting the key in your database. It doesn’t matter if you use the same passphrase both times. This passphrase is not recoverable, so make sure you remember it. You will also be asked what you want to call the certificate; it makes no difference to anyone what you call it, but you can’t have two certificates with the same nickname.

Make note of the hash of your key. You can retrieve this hash from the line “added private key” followed by a path and a hexadecimal number ending in “.0″. Find the line in your .muttrc that says:

# ~/.mutt/smime.rc
set smime_default_key="12345678.0"

and change “12345678.0″ to the hash for your key that you took note of. The only thing left to do is to install the Comodo root certificates. These are already installed on your system in “/etc/ssl/certs/Comodo*” and “/etc/ssl/certs/COMODO*”. For each of those root certs (I’m actually not sure which is needed for your personal cert), you need to issue the following command:

$ smime_keys add_root /etc/ssl/certs/Comodo_Secure_Services_root.pem

You have now successfully setup your environment to use S/MIME with Mutt. Now let’s look at the configs. For the gpg.rc config, I kept everything default except for the following:

# ~/.mutt/gpg.rc
set pgp_good_sign="^gpg: Good signature from"
set crypt_autosign="yes"
set crypt_replysign="yes"
set crypt_replysignencrypted="yes"
set pgp_auto_decode="yes"
unset smime_is_default

For the smime.rc config, again I kept everything default except for the following:

# ~/.mutt/smime.rc
set smime_is_default="yes"
set crypt_autosmime="yes"
set pgp_autosign="no"
set smime_timeout="300"
set crypt_autosign="yes"
set crypt_replyencrypt="yes"
set crypt_replysign="yes"
set crypt_replysignencrypted="yes"
set crypt_verify_sig="yes"
set smime_default_key="12345678.0" # you should have already changed this

You are now ready to roll. When you change to your personal account, it should use PGP/MIME by default, and when you change to your work account, it should use S/MIME by default.

Use Your SSH Client To Help Prevent Stupid Mistakes

I have chosen the path of system administration for my career. It’s been very rewarding, and I really love my job. However, there are times when I make stupid mistakes that cost others money. I’m sure we’ve all been there. It’s stressful, embarrassing and can really shake you up, if you mistake is bad enough. Many times, this happens because you fat-fingered an IP address, hostname, or something else, and your SSH client takes you somewhere you shouldn’t be. If that’s the case, hopefully this post can help.

According to the ssh_config(5) manual:

     LocalCommand
             Specifies a command to execute on the local machine after suc‐
             cessfully connecting to the server.  The command string extends
             to the end of the line, and is executed with the user's shell.
             The following escape character substitutions will be performed:
             ‘%d’ (local user's home directory), ‘%h’ (remote host name), ‘%l’
             (local host name), ‘%n’ (host name as provided on the command
             line), ‘%p’ (remote port), ‘%r’ (remote user name) or ‘%u’ (local
             user name).

             The command is run synchronously and does not have access to the
             session of the ssh(1) that spawned it.  It should not be used for
             interactive commands.

             This directive is ignored unless PermitLocalCommand has been
             enabled.

As mentioned, the used of LocalCommand executes a local command after successfully connecting to the server. I figured this would be a great way to print something to the terminal, letting me know whether or not my client just connected to a production machine, a QA machine, or a development machine.

I wanted to use colors, to make it obvious. I don’t want to make the same mistake twice, so I want it painfully clear what machine I just went to. As a result, if I go to a development or home machine, use green. If I enter a QA machine, use yellow. If I enter a production, or other serious machine I probably shouldn’t be on, use red. As a result, I can take advantage of the ANSI escape sequences for color. In case you forgot, here are the colors and modes:

Colors
\e[{attr1;…;{attrN}m

Text attributes
0 Reset
1 Bright
2 Dim
4 Underscore
5 Blink
7 Reverse
8 Hidden

Foreground Colors
30 Black
31 Red
32 Green
33 Yellow
34 Blue
35 Magenta
36 Cyan
37 White

Background Colors
40 Black
41 Red
42 Green
43 Yellow
44 Blue
45 Magenta
46 Cyan
47 White

So, if I were about to SSH to a production machine, I probably want to make it as obvious as possible. Thus, I could print to the terminal, in blinking, bold, red text “PRODUCTION”. I could use the following command:

print "\e[1;5;31PRODUCTIONm\e[0;m"

Notice that at the end of the sequence, I’m resetting the text attributes. This is because if you don’t do this, you will keep the text attributes in your terminal, and that may have an affect on how the text is displayed when in your remote SSH connection.

A possible ~/.ssh/config file could look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Host development
    Hostname dev.domain.tld
    LocalCommand print "\e[1;32mDevelopment\e[0;m"
    PermitLocalCommand yes

Host qa
    Hostname qa.domain.tld
    LocalCommand print "\e[1;33mQuality Assurance\e[0;m"
    PermitLocalCommand yes

Host production
    Hostname prod.domain.tld
    LocalCommand print "\e[1;5;32mPRODUCTION\e[0;m"
    PermitLocalCommand yes

Here is a screenshot in action (without the blink):

My Tmux Hardstatus Theme

Recently, I’ve made the switch from GNU Screen to Tmux for my remote terminal multiplexor. I still prefer GNU Screen for serial connections, however (something the Tmux developers don’t seem to think is important). So, when getting it setup, I wanted my hardstatus line to imitate my GNU Screen hardstatus line as closely as possible. Well, I got it to that point, then took it even further to work with my custom Irssi and ZSH themes (I want everything to tie in nicely). The only thing left is getting Mutt in order, but that’s for another post.

At any event, here is the configuration for the theme:

1
2
3
4
5
6
7
8
9
10
11
12
# hardstatus line theme
set-option -g status-fg white
set-option -g status-bg default
set-option -g status-justify centre
set-option -g status-left-length 13
set-option -g status-left '#[fg=green][ #[fg=black,bright]#h #[fg=green,nobright]][#[default]'
set-option -g status-right-length 16
set-option -g status-right '#[fg=green]][ #[fg=black,bright]%m/%d %H:%M #[fg=green,nobright]]#[fg=default]'
set-window-option -g window-status-current-format '#[fg=red,bg=default]( #[fg=white,bright,bg=default]#I:#W#[fg=red,nobright,bg=default] )#[fg=default]'
set-window-option -g window-status-alert-attr bold
set-window-option -g window-status-alert-fg yellow
set-window-option -g window-status-alert-bg default

Obviously, this won’t look that great on a terminal with a white background (or really any color other than black). And here is the screenshot:

As you can clearly see, the active window you’re under is bold white with red parentheses around the window name. The previous window you were in is marked with a dash ‘-’ (by default). An alert in a terminal will change the text to bold yellow, so long as you’re not in that window (as you can see with the “mutt” window). It ties in nicely with the 88_madcows.theme file for Irssi, and the ZSH theme I built.

I’m new to building Tmux hardstatus lines, so if there is something I should be doing differently, let me know.

I Am Going To OLF

I will be attending the Ohio Linux Fest this September (in about two weeks) giving a talk on “Password Theory and Breaking Encrypted Filesystems”. The talk covers some theory on what exactly makes a “secure password”, including some mathematics, entropy, random number generators, shadowed passwords, salts, rainbow tables and cryptographic hashes. I end the talk by showing how to break into an encrypted filesystem, regardless of the type of encryption, or the software used to encrypt the filesystem. It should be a good talk. When my slides are ready, I’ll make them available online.

If you have thought about attending, you should register. You can see my talk, if you sign up just for the enthusiast package. You can attend a sponsored lunch (and other things) if you upgrade.

Also, I’ll be hosting the PGP keysigning party at the conference as well (a follow-up post is coming). My key is in the “strong set”, so by me signing your key, I’ll also be bringing you into the strong set as well, if you’re currently not in it. It’s all about strengthening the Web of Trust.

At any event, see you at the fest!

Pimp My Irssi – Part 2

It’s been over 3 years since I wrote the original article about pimping out Irssi, with various themes, scripts, aliases, etc. Well, I figure it’s probably time for an update. After all, if you know anything about me, you know I’m an IRC junkie with Irssi, and currently having a love affair with Bitlbee.

Aliases
I’ve only added two aliases to Irssi since we’ve last met. The first alias comes from the main Irssi.org website. If you scroll to the bottom of the page, there is a tip close to the end for adding all open channels to your “/channel list”. The only thing it was missing was saving the window layout to the config, so next time you open your Irssi, not only will you be rejoined to all of your channels, but they’ll all be in the same place they were last time. Here’s the alias:

/alias CHANNADD script exec foreach my \$channel (Irssi::channels()) { Irssi::command(“channel add -auto \$channel->{name} \$channel->{server}->{tag} \$channel->{key}”)\;}; layout save; save

This next alias will effectively “mark all as read” for your channels. For whatever reason, you may like to have a clean slate for channel activity in your statusbar, rather than all the channels showing some form of activity. This alias will clean up your statusbar, so any new activity becomes immediately available. As mentioned, think of this as “marking all channels as read”:

/alias READ script exec \$_->activity(0) for Irssi::windows

Scripts
My scripts have changed a little bit, but not by much. Really, there’s only two scripts worth mentioning about that I haven’t already done so in the previous post.

The first script is similar to “screen_away.pl“, except for tmux(1). I’ve adopted nesting Irssi behind tmux(1) instead of screen(1) because I just couldn’t get bolded black and white to work correctly. Now, everything looks as it should, with zero formatting issues. At any event, “tmux_away.pl” does the same thing, in that it sets your “/away” status when you detach your session, and resets it when you reattach.

The second script is “trigger.pl“. This script is mostly a search/replace script for events that happen in the channel. For example, if you don’t like the “F-word”, you can change it to something less vulgar with trigger.pl. It can handle much more, but I only use it mainly for that purpose. The triggers I’ve set up this far are as follows:

-publics -regexp ‘Message from unknown participant ‘ -replace ”
-all -nocase -regexp ‘</?(a|b|body|div|em|font|i|s|u)( +\w+=”.*?”)*>’ -replace ”
-privmsgs -nocase -regexp ‘&amp;’ -replace ‘&’
-privmsgs -nocase -regexp ‘&gt;’ -replace ‘>’
-privmsgs -nocase -regexp ‘&lt;’ -replace ‘<'
-privmsgs -nocase -regexp '&quot;' -replace '"'
-publics -masks 'update!update@identi.ca' -channels '&bitlbee' -regexp '^aaron: ' -replace ''

All of my triggers are Bitlbee triggers. Let’s cover each trigger that I’ve created, just so there’s no confusion:

  1. When joining Jabber MUCs with Bitlbee, the Jabber server you’re connecting to can be configured to print the past 20 lines (or whatever) of the previous log, so you can get caught up to speed on the discussion quickly. However, if the user that said something in that log is not in the MUC when you join, you’ll see “Message from unknown participant” in the backlog. This trigger removes that completely.
  2. When Pidgin or Adium users get online, sometimes the clients send HTML/XML to Bitlbee. THis trigger strips the HTML/XML tags as listed completely.
  3. Similar to trigger #2, this trigger replaces the HTML “&amp;” with “&”;
  4. Similar to trigger #2, this trigger replaces the HTML “&gt;” with “>”;
  5. Similar to trigger #2, this trigger replaces the HTML “&lt;” with “<";
  6. Similar to trigger #2, this trigger replaces the HTML “&quot;” with ‘”‘;
  7. I use Identi.ca with the XMPP bot in the “&bitlbee” channel. I know the bot is addressing everything to me, so I don’t want to see each notice begin with “aaron: “, so I’ve stripped that out completely, so the notice actually starts with the user nickname. If you’re interfacing with the bot in a private channel, rather than in “&bitlbee”, then this trigger won’t do much good for you. You’ll need to modify it.

Theme
As much as I try to do a new theme, I always come back to my custom-built “madcow.theme” called “88_madcows.theme“. It’s the awesome. Screenshot

Fully Mobile

This blog is now fully mobile. If you visit http://pthree.org with your mobile browser, you should be taken to a mobile version of the site. It’s only using browser detection, rather than domain mapping, as I’m not in the mood to create A records for m.pthree.org, which only ends up making the URL longer anyway. This has been up for a while.

Mobile screenshot of http://pthree.org

Further more, I’ve added shortlinks to every post. Rather than the lengthy pretty URLs of http://pthree.org/2001/07/22/fully-mobile, you should be able to also visit http://pthree.org/?p=1956, and reach the same place. You can find the shortlinks on the left side of each post from the main page, or at the bottom of the post, when at a specific post. This makes it nicer to type in your mobile device, or share with users via the various messaging options- SMS, IM, IRC, Twitter, Open Microblogging, etc. You can click on the title for the permalink.

If that’s not enough, I’ve taken the shortlink of each post, and created a QR Code from it, in case you are at the computer with your phone, and wish to read the post at a later date. It’s located at the upper left of the blog site. It won’t appear on the mobile version of the site (that wouldn’t make much sense, now would it?). If at the main page, it is the URL of the blog. You’ll even find a QR Code at my contact page (which will actually show on your mobile browser- meh).

I’m ready for the mobile revolution.

OpenSSH Best Practices

This post comes from Matt Taggart, who put together a document about the best practices for using OpenSSH. A lot of the points brought up in that document rang the bells of common sense, and are so good, it’s worth blogging about in hopes that the points mentioned therein reach as many as possible. I’ve also added a couple extra points that I’ve learned with my experience using OpenSSH.

These are best practices from the client perspective, not the server. Many of these points you will have already been familiar with, but some of them not as much. If you sit down and think about what you are doing as a client when you SSH to a server, some of the implications mentioned here make sense.

Lastly, security is a big topic, and not something that can be flipped on and off with a switch. Security always starts with the user. Unfortunately, increasing your security could mean making usability more of a pain in the rear. However, as an OpenSSH client, I hope the techniques mentioned here won’t decrease your usability too bad, while greatly increasing your overall OpenSSH security. With that said, let’s get started.

0. Use ECC first, then RSA, then DSA with maximum bit strength.
When generating your OpenSSH keys, you should be aware of the cryptographic algorithms of the OpenSSH server that you are accessing, and what you can and cannot use. As of OpenSSH version 5.7, elliptic curve cryptography is a supported algorithm. It is proving to be a very secure, robust and light crypto algorithm, but it also must be supported by both the client and the remote server. This means that both the client and the server must be relatively new installations of OpenSSH- something that RHEL 6 and earlier, Debian GNU/Linux Stable 6 and earlier, Ubuntu 10.10 and earlier, and likely many other stable releases from other GNU/Linux operating systems, do not support. When you can, use elliptic curve cryptography for your SSH keys.

If ECC is not available on either your client or server, then you should choose RSA as your key’s crypto. DSA suffers from a weakness, where if the host does not have a sufficiently strong pseudorandom number generator (PRNG), then the “random k” could become exposed from the public key, allowing the attacker to build the private key from the public. The PRNG supplied by GNU/Linux (the device file “/dev/urandom”) is sufficiently strong, providing good random data from entropy pools- thus, GNU/Linux generally doesn’t suffer from this problem. Other operating systems could.

A great demonstration of DSA’s weakness can be found in this excellent blog post, where the author demonstrates how trivial it is to build the private key when the “random k value” is known. Fortunately, RSA does not suffer from this weakness, and also allows you to build larger keys than DSA.

If neither ECC nor RSA is supported by the client nor server, as is the case with some archaic proprietary SSH implementations, then DSA is your only option. Unfortunately, it is also the default for OpenSSH when generating a key. So, you should always get into the habit of passing the “-t [type]” switch when generating your keys.

In all 3 cases, where possible, you should choose the maximum bit strength that the algorithm allows. This will put a bit of strain on the client’s CPU, but it will also give you the greatest strength when authenticating on the wire. When generating your key, use the “-b [size]” switch to specify the bit strength.

1. Use SSH keys and make your servers require them.
There are three reasons why you would want to use SSH keys:

  1. SSH keys with a passphrase provide two-factor authentication.
  2. SSH passwords can be read in plain text on the remote server.
  3. SSH keys aren’t subject to brute force dictionary attacks, like passwords.

Let’s cover each in detail. First, two-factor authentication. SSH keys use public key cryptography. You are given a private and public key when generated. During generation, you are asked to provide a passphrase for the private key. DO NOT GIVE IT AN EMPTY PASSPHRASE! By providing a passphrase to your key, you have enabled the two-factor authentication- something you have (the key) and something you know (the passphrase). Using SSH keys can be troublesome, however. As a result, take advantage of the SSH agent for your system to cache the passphrase locally on your client. This will increase your usability by only entering your key passphrase once, and using the agent to login to other servers without providing the key passphrase again.

Second is reading the user password in plain text on the remote SSH server. You may not think this is possible, as everything in OpenSSH is encrypted, right? Wrong. The two Achilles Heel’s in the connection are the client and servers themselves, where the decryption is taking place. Other users, specifically those who have superuser access, can exploit this. To demonstrate this, make a connection to a server that you have superuser access on. Then, from the client initiate a connection that would require your server password, but don’t supply it. Go back to the server, and find the process of the connection, and run an strace on the PID. Go back to the client, and type in your password. Watch, very likely in horror, the password be displayed on your console.

Here is an excellent writeup by Joseph Hall on this very issue. The problem lies in whether or not you trust those who have superuser access on the server. You should only trust them enough to do their job on the server, and nothing more. Just because they have superuser access on the server, doesn’t mean they can be trusted with your banking account information. Because people use the same passwords over and over across multiple accounts, it’s likely that the password sniffed out of the connection is the same password for their email account. Or bank.

Third, as should be obvious, SSH keys aren’t subject to brute force dictionary attacks like passwords are. If you control the SSH server, and require that SSH keys are the mode of authentication, then brute force attacks will be in vain, regardless how long they try. If you have a publicly facing SSH server, you’re likely aware of how hard your server gets hit from attackers all over the world. By forcing key authentication, all those attacks are in vain.

2. Don’t use a blank passphrase on your keys.
This should come as no surprise, but needs to be mentioned. Your SSH keys are something that should be guarded carefully, with sufficient paranoia. If for any reason, your SSH client is compromised, your SSH keys are a way in to the remote servers that you have access to. If your keys are not protected by passphrases, then after scouring your shell history, or SSH config for hosts to connect to, they’re in the SSH server with little effort. You must protect your keys with strong passphrases!

Now, I understand that there are some like me, who use SSH as the connection for nightly local backups, at which point the client will be asked for the passphrase of the SSH key. Because you wish this to be an automated process, and likely when you’re in bed, you won’t be available all the time to provide the credentials. So, you create an SSH keypair that is not passphrase protected. In such a scenario, here is what I would do:

  1. Only install this key on the backup SSH server, and no where else.
  2. Do not install this key into an account that has superuser access.
  3. Do not install this key into the superuser account.
  4. On the backup server, change the key entry in the authorized_keys file to only allow connections from that client using that key (documented how below).

The first, second and third points are easy enough to configure, but how do you configure the fourth point, and is it even possible? When you copy the key to the authorized_keys file on the SSH server, it could look something like this:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzoblHIUARNP5Kq12QwUqxB6T7m8TWti4LIFcvOCa...

Change the beginning of that entry to this:

from="10.19.84.10",command="/home/user/bin/validate.sh" ssh-rsa AAAAB3NzaC1y...

This tells the server that the only connections allowed to use this key can come from “10.19.84.10″, and when the connection is made, a local script is ran called “validate.sh”. Here are the contents of that script for me:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/sh

case "$SSH_ORIGINAL_COMMAND" in
    *\&*)
        echo "Rejected"
    ;;
    *\(*)
        echo "Rejected"
    ;;
    *\{*)
        echo "Rejected"
    ;;
    *\;*)
        echo "Rejected"
    ;;
    *\<*)
        echo "Rejected"
    ;;
    *\`*)
        echo "Rejected"
    ;;
    *\|*)
        echo "Rejected"
    ;;
    rsync\ --server*)
        $SSH_ORIGINAL_COMMAND
    ;;
    *)
        echo "Rejected"
    ;;
esac

Make sure the script is executable by the user account on the SSH server, and test it before committing to it as part of your backup policy. If the client host is behind a dynamic IP address, or some other variable that prevents it from having a static address, you can remove the “from=” part, but leave the “command=” part. The goal is to minimize damage that can be done with that key.

Again, this is all if you need to perform an automated backup with SSH keys, where a passphrase cannot be performed. In almost every other case, your SSH key should be protected by a good, strong, loaded with entropy passphrase. Using one from a passwordcard is probably best.

3. Use a separate key for every client you SSH from.
I admit that when I first started using SSH, this didn’t make much sense to me. The amount of keys that I generated was a lot, and managing them became somewhat of a pain. Then, when becoming system administrator of a large organization, and controlling upwards of 300 servers, managing that many keys become immensely intense.

I soon came to the realization that it wasn’t that big of a deal. It is trivial to copy the key to the remote host (this can be done with the “ssh-copy-id(1)” command). Further, for work SSH keys, while I am in charge of managing those keys, I should only worry about work keys at work, and home keys at home. In other words, separate the management of the keys.

But the point of this is to NOT copy the same client key to multiple clients. Think about it. By copying the key around to multiple clients, this means that the key is on every server you ever access from those clients, even if some of the other clients cannot access that server directly. Thus, if a client is compromised, and the key is stolen, it’s difficult to know which client was compromised, and all servers that have that key in their authorized_keys file, are subject to compromise. If you have a different key for each client, then those keys are only on the servers that the client has direct access to, and should a client become compromised, you know which servers to saefguard, and damage is minimal.

4. Limit the number of clients you SSH from.
If an attacker can compromise your client, then they can get access to your SSH keys, as they are stored on the filesystem. Further, they may be able to install a keylogger to log passwords and passphrases, including those for your key. Once this information is gained, then all the accounts on the servers the key is installed on are now compromised as well. By limiting the number of clients you SSH from, you minimize the exposure of SSH servers to the attacker.

5. Don’t “chain” or “loop” logins, but do “star”.

The point relates to the one above it, namely limiting the number of hosts you SSH FROM. There are a few scenarios on how you can create SSH sessions:

  • Chain: As a client, you make a connection with an SSH server. Then, from that server, you make another connection to a different SSH server. Once, twice, three times or more, you’ve created a chain of connections from the client to the final host.
  • Loop: As a client, you make a connection with an SSH server. Then, from that server, you make a connection back to the client you started from, thus creating a loop with your connections.
  • Star: As a client, one connection is made to an SSH server. If another connection is needed to a different SSH server, this is made from the client. For each connection, the original client makes it.

The reasons why this is a “best practice” might not be obvious. Let’s start first with chaining connections. If one client is compromised in the chain, the other clients in the chain might possibly be compromised using the same method. Thus, all connections in the chain could become compromised. And a loop is nothing more than a specific instance of a chain.

Of course, this isn’t always possible. Maybe a chain is the only way to get to an SSH server on a private VLAN or behind a DMZ. These connections might be necessary (typically called “jump hosts”), but they should be used with caution, and as little as possible. When you are done with your task, rather than idle the SSH connection, terminate it to minimize exposure, should an attack occur.

When using a jump host, install netcat(1) on the jump host and use the ProxyCommand configuration paramater. Something like this would be sufficient:

Host inaccessiblehost1 inaccessiblehost2
   ProxyCommand ssh accessiblehost nc -q0 %h %p

With star connections, you minimize the risk of compromise with each of your connections, but security is maximized, even if extra work is required on your end. For example, if you wish to transfer data from one SSH server to another, this may mean bringing the data to the client, then sending it to the destination server.


6. Consider disabling the SSH server on the client you are connecting from.
This rule shouldn’t apply only to the SSH server, but to any daemon you have running on your machine. If you don’t need a service running, then turn it off. By doing so, you minimize the attack vector and greatly increase your security. OpenBSD prides itself in having only two remote holes in the default install in a heck of a long time, but then it also doesn’t have any services running on a default install either.

So, for SSH, because you followed rule #5, and you aren’t doing “chain” or “loop” connections from your client, then this means that you’re not connecting to your own machine that you started your initial connection from. I understand that this isn’t always possible. I have 300+ SSH servers at work, and I can’t possible turn off the SSH server on a host, just because I’m connecting from it. But then, do I need an SSH server on my virtual laptop? Not likely, and if there are things I need, I can turn it on, do my work, then turn it off.

7. Don’t ignore SSH host key warnings.
When you install an SSH server for the first time, it creates a server public and private keypair. This set of keys is what is used for the encryption and decryption between your client and the SSH server. Thus, all traffic that you are sending to that server, is done because you trust that the SSH server key presented to you, is indeed the key of the server itself. So, what happens when you connect a different time, and your client warns you that the public SSH server key has changed? Should you trust the connection?

Depends. Usually, it’s due to the fact that you either reinstalled the SSH server or reinstalled the operating system. In this case, you can move forward, so long as you know that the key presented is the new key from the server. However, someone could setup a proxy SSH server, for the intent of gaining system passwords. Your client will warn you the key is different, and you should pay attention to the warning.

So, in your SSH client config, you generally should not set the following:

Host *
    StrictHostKeyChecking no

Default is “yes”, and it should stay yes in your config. OpenSSH is verbose enough for your benefit. Try to take advantage of it, rather than silence it, or ignore it. After all, it’s your data.

8. Be wary of using X11 forwarding.
While taking advantage of the ability to run remote X applications locally on your client is nice, it has some very grave drawbacks. For example, it’s common for people to launch a remote browser, such as Firefox. What isn’t realized, is that you’re providing usernames and passwords through the browser, which could be caught on the remote machine from which the app is running (taking advantage of X events, for example).

There is a time and a place for X11 forwarding, and I have benefited by it, but generally, it’s not needed. Set the following in your SSH client config, and only enable it when needed:

Host *
    ForwardX11 no

9. Don’t use agent forwarding.
As with X11 forwarding, you are giving ultimate trust to the remote host when forwarding your local agent. If that connection makes a connection to an account with superuser privileges, then a user on the remote SSH server could hijack your agent by connecting to the socket the SSH server creates.

Also, on the client initiating the connection, the superuser must be trusted, which isn’t always the case. The local superuser can access the agent socket on the client, and attack. Thus, it’s generally not a good idea to enable agent forwarding. Thus, as it is by default, the following should be sent in your client SSH config:

Host *
    ForwardAgent no

Improved Twitter Integration In Bitlbee

I just recently received the Bitlbee 3.0.3 update in Debian Sid, so I thought I would checkout the changelog, and see if there is anything I would get excited about. And indeed, there is. Very much so. Here’s the relevant changelog:

Version 3.0.3:
- Fixed Twitter compatibility. (The API call used to get the following list was deprecated.)
- Twitter: Enable the show_ids setting to assign a two-digit short ID to recent tweets to use for retweets and replies (so you can RT/reply to more than just a person’s last message).
- Some other Twitter fixes/improvements.
- “otr reconnect” command and some other fixes.
- GnuTLS 2.12 compatibility fix.
- Include “FLOOD=0/9999″ in the 005/ISUPPORT line at login to hint the IRC client that rate limiting is not required. (Next step: Get IRC clients to parse it.)
- Other stuff too small to mention.

The second point in the changelog got me pretty excited. To appreciate this, let me give you some background. I’m an Identi.ca user first, Twitter user second. The main reason for this is the integrated XMPP support. I’d much rather drink from the fire hose, then wait for refresh intervals to give me notice dumps. I want the data live, as it happens, in real time. Twitter used to have an XMPP bot, but I guess they couldn’t scale it well enough, and ended up pulling it.

Anyway, with Identi.ca, when using the XMPP bot, you get the notice ID at the end of each “dent”. Something like this:

toros: !Ubuntu Cloud Portal: Zero to Ensemble in 5 mins http://goo.gl/J1Iby [76347696]

I can reply directly to that notice, rather than just replying to the last notice of @toros, by sending “reply #[notice_id]” to the XMPP bot. Then, everything stays in context on the website. Further, Identi.ca keeps a stellar view of contextual threads, as shown in this example, something Twitter could learn from.

However, with previous versions of Bitlbee, all you could do with Twitter was reply to the last notice, rather than a specific notice. This was frustrating, as other clients have been able to keep things in context if implemented correctly. Well, the recent change fixes that. Now, at the beginning of each message, there is a short two-digit number identifying that notice. This number is unique to your running instance of Bitlbee. Further, if a reply or retweet is sent to you, you can see which notice the reply is referring to, which makes it trivial to scroll through your back buffer to find the post you sent, in case you forgot.

At any rate, here’s a screenshot of Twitter in action with the new release. Notice the hilights, the notice IDs and the references to other posts. Pretty slick. Here’s how you set it up:

  1. Upgrade Bitlbee to 3.0.3, using either your operating system repository, or using the upstream tarball.
  2. Restart Bitlbee after the upgrade is successful.
  3. From the Bitlbee window, disconnect from your Twitter account.
  4. Type “account # set show_ids true” where “#” is the account number for your Twitter connection.
  5. Reconnect to your Twitter account.
  6. Profit!

If you still don’t have the notice IDs for each post, you may need to disconnect from Bitlbee entirely in your IRC client, and reconnect.

Now, the only thing left to do is reply to a notice. Use “reply #” to send an automated @-reply to that user, as follows:

< nixternal> [45->44] @AaronToponce if I am not on IRC much, I don’t need irssi much. Is bitlbee still being developed? Plus it doesn’t suit my workflow
< aaron> reply 45 oh yes, very active development. new release has much improved twitter integration that i really, _really_ dig
< root> You: [47->45] @nixternal oh yes, very active development. new release has much improved twitter integration that i really, _really_ dig

Notice that I just typed “reply 45 oh yes, …” and “@nixternal” was sent in its place. For me, this is a VERY welcomed feature, and Twitter sucks much less than it did before. But, not all is peaches and cream. After 100 notices scroll by your screen, the counter resets. This could be problematic if you wish to reply to an old Tweet that was several hours ago, because you were away from your computer. Using “reply ## foo bar baz” will result in sending the reply to the most recent ##, rather than the intended one, which may not even be the same user. And, if using the standard @-reply, the reply will go to the most recent post, which means you might be out of context. Still, I welcome the change, as it’s a massive improvement in my eyes over what was previous.

While Identi.ca is still my #1 (for other reasons than just the XMPP bot), Twitter has now become a new toy to play with, given these additions. Wilmer, my hat goes off to you my friend, you are turning out a spectacular product, that I absolutely love. Keep up the amazing work!

Tagged

Thirtyfour?

What’s that you say? Cryptic message hidden in Morse Code. Can you crack it?

Poll: Have You Ever Used A Floppy Disk?

This post is a quickie to see what the current generation is like these days. I’m an old fart (not as old as many reading this post), but I remember when 5 1/4″ floppy drives were “standard”, and 3 1/2″ were the new fad. Then came Iomega Jazz drives, and the like. CDRW hit the scene, never really went far, then USB storage was here, and here to stay.

At any event, in graphical user interfaces, you’ll see floppy disks that represent saving a file to disk. It’s very, very common, yet I doubt many of the younger generation has ever used one. So, how are they supposed to know what it does?

So, here’s a poll for you to take. You’ll need to take the poll at my site, as it uses Ajax calls to the page, which means it won’t work in your RSS reader, or on any other site. I’m just curious to see what falls out.

Have you ever used a floppy disk?
View Results

Outlook Insanity

I posted this to my local LUG this morning, then realized that it would make an excellent blog post, so I’m cross posting it here for a wider audience.

For those who know me, know I’m anal retentive about my mail. It started probably 4-5 years ago, when I discovered the difference between the IMAP and POP protocols. Following that, I learned server-side filtering, content encoding, MIME types, and a bazillion other things about electronic mail. Needless to say, I have an OCD with mail.

At any rate, someone on the mutt-users mailing list raised an interesting question, and I thought I would share that with you here. Essentially, Outlook 2007 (and probably previous versions) is using the following format to structure their paragraphs:

<p>Lorem ipsum<o:p></o:p></p>

In case you’re curious, and don’t know what the “<o:p></o:p>” tags are, you’re in good company. They’re Microsoft Office namespace tags. I’m not entirely clear of what they’re function is, but it’s common for Word, Outlook, and other Microsoft Office products to use them when composing HTML.

What this means for Mutt users is extra line breaks. Rather than one line break, there are two, and I believe the “<o:p></o:p>” tags are the culprit for adding the extra line break (seeing as though properly formatted paragraphs wrapped in <p> tags shouldn’t do doing so).

However, here’s the real kicker- I sent myself a test email that had Lorem Ipsum content, just to troubleshoot the issue a bit. The plain text of the mail, including headers, is roughly 4 KB. However, the HTML of the message is about 16 KB! The message grew 4 times!!

Call me a fanboy, call me stupid, call me late for dinner, but growing a message 4 times, just to wrap it in HTML? Really? It seems that Outlook is sending both the plain text and the HTML-wrapped mail together, not to mention the extra header and boundary information. But to grow a message 4 times larger than the original plain text?

What in the world are they adding? Well, there is the additional header and boundary information, which in reality, isn’t that much. What is killing them, are all the CSS and HTML tag attributes, not to mention sending both the plain text and HTML-formatted version of the message. In other words, metadata. To. Send. You. The. Same. Message. As. Plain. Text.

Ugh, and to think it gets worse.

If I digitally sign, not encrypt, but sign the message with my PKI key that my employer has allowed me to setup, the message grows to 29 KB! This is more than 7 times the original plain text, just my adding my SSL signature. The S/MIME signature alone that is attached to the mail is 1/5 the size of my entire public GnuPG key!

Anyway, I was blown away when I saw this. I’ve heard of Exchange administrators hating their jobs, because of the constant battles with it. I would imagine that Outlook isn’t helping any by composing emails on these orders of magnitudes.

Just thought I would share. Oh, and if you have a solution to stripping out the “<o:p></o:p>” tags in Mutt, I’m all eyes.

My Journey Through Mathematics


A photo of me and my library of math books that I studied to walk with a Bachelor’s of Science in Applied Mathematics.

As of April 22, 2011, I have a Bachelors of Science degree in Mathematics, with an emphasis in applied math, and a minor in Computer Science, with an emphasis towards software development. While going through my college career in math, I wanted to take as many diverse electives as I could, while still maintaining the requirements for graduation in a timely manner. What resulted was not only study a great deal of applied mathematics, but also reaching the requirements for a an emphasis in general mathematics theory as well (even though the university won’t give me a second emphasis).

Here are the classes I studied, and the topics discussed in each class:

Precalculus:

  1. Graphs
  2. Functions and Their Graphs
  3. Polynomial and Rational Functions
  4. Exponential and Logarithmic Functions
  5. Trigonometric Functions
  6. Analytic Trigonometry
  7. Applications of Trigonometric Functions
  8. Polar Coordinates and Vectors
  9. Analytic Geometry
  10. Systems of Equations and Inequalities
  11. Sequences, Mathematical Induction and the Binomial Theorem
  12. Counting and Probability

Single Variable Calculus I:

  1. Function and Models
  2. Limits and Rates of Change
  3. Derivatives
  4. Applications of Differentiation
  5. Integrals
  6. Applications of Integration

Single Variable Calculus II:

  1. Inverse Functions
  2. Techniques of Integration
  3. Further Applications of Integration
  4. Differential Equations
  5. Parametric Equations and Polar Coordinates
  6. Infinite Sequences and Series

Multivariate Calculus:

  1. Vectors and the Geometry of Space
  2. Vector Functions
  3. Partial Derivatives
  4. Multiple Integrals
  5. Vector Calculus
  6. Second-Order Differential Equations

Discrete Mathematics:

  1. Logic, Sets and Functions
  2. Algorithms, Integers and Matrices
  3. Mathematical Reasoning
  4. Counting
  5. Advanced Counting Techniques
  6. Relations
  7. Graphs
  8. Trees
  9. Boolean Algebra
  10. Modeling Computation

Ordinary Differential Equations:

  1. Classifications
  2. First Order
  3. Second Order
  4. Higher Order
  5. Series Solutions of Second Order
  6. The Laplace Transform

Elementary Linear Algebra:

  1. Vectors
  2. Solving Linear Equations
  3. Vector Spaces and Subspaces
  4. Orthogonality
  5. Determinants
  6. Eigenvalues and Eigenvectors
  7. Linear Transformations
  8. Applications of Linear Algebra

Probability and Statistics I:

  1. Historical Summary
  2. Probability
  3. Random Variables
  4. Special Distributions
  5. Estimation

Dynamical Systems:

  1. Differential Equations
  2. Planar Systems
  3. Interacting Species
  4. Limit Cycles
  5. Hamiltonian Systems, Lyapunov Functions and Stability
  6. Bifurcation Theory
  7. Three-Dimensional Autonomous Systems and Chaos

Mathematical Modeling:

  1. One Variable Optimization
  2. Multivariable Optimization
  3. Computational Methods for Optimization
  4. Introduction to Dynamic Models
  5. Analysis of Dynamic Models
  6. Simulation of Dynamic Models
  7. Probability Models
  8. Stochastic Models

Elementary Topology:

  1. Set Theory and Logic
  2. Topological Spaces and Continuous Functions
  3. Connectedness and Compactness
  4. Countability and Separation Axioms

Numerical Analysis I:

  1. Preliminaries
  2. Solutions of Equations in One Variable
  3. Interpolation and Polynomial Approximation
  4. Numerical Differentiation and Integration
  5. Initial-Value Problems for Ordinary Differential Equations
  6. Direct Methods for Solving Linear Systems

Number Theory:

  1. The Integers
  2. Integer Representations and Operations
  3. Primes and Greatest Common Divisors
  4. Congruences
  5. Applications of Congruences
  6. Special Congruences
  7. Multiplicative Functions
  8. Cryptology
  9. Primitive Roots

Elementary Real Analysis I:

  1. Properties of the Real Numbers
  2. Sequences
  3. Sets of Real Numbers
  4. Continuous Functions
  5. Differentiation
  6. Integration

Elementary Real Analysis II:

  1. Infinite Sums
  2. Dense Sets, Oscillation and Continuity on Sets
  3. Sequences and Series of Functions
  4. Power Series
  5. Measure Theory
  6. Lebesgue Integration

Even though I’ve graduated with a math degree, I think I would like to attend school further to pick up Modern Algebra I and II, Complex Analysis, Matrix Theory and maybe one or two more before attempting the math GRE and applying for graduate school. There are many more math classes in the undergraduate program to take, such as History of Mathematics, Boundary Value Problems, Partial Differential Equations, Probability and Statistics II, Numerical Analysis II, Enumeration, Euclidean and Non-Euclidean Geometry and Graph Theory.

I’ve found a website that aggregates free electronic books in various formats, such as PDF. Tons and tons of mathematics books are referenced to on the site, many of which I’ve downloaded and begun reading. The site is: http://e-booksdirectory.com/listing.php?category=3. I hope I never lose my passion for

Convert Text To Base-64 By Hand

When I was a kid, I had this fascination with cryptography. I learned and used, as most kids to, the Caesar cipher first (using my trusty Captain Crunch Decoder Ring), then later learned and used the Affine cipher. It was great for passing notes in class when I was in elementary and secondary education. I even learned the ancient runes, and used those quite a bit too.

Since then, I’ve been fascinated by hand cipher techniques, and I’ve learned a few historical ones over the years. I’ve even invented my own hand cipher, even though I doubt it would show any form of cryptanalytic strength. While I don’t do anything with hand ciphers practically, I still consider it a fun skill to have, whether or not it actually proves to be useful (when I was a Boy Scout, I always wanted to learn Morse Code, so I could tap out answers to a quiz or test in class to a fiend, and back to me without anyone knowing. How cool would that be?!).

While I know base-64 is not considered a cipher algorithm, I thought to myself that I don’t know how to convert a string of ASCII text to base-64 by hand. So, I figured I might as well learn. It could be an interesting skill to add to my own hand cipher, and could even prove to be useful around the house. So, if you’re curious, here we go.

STEP ONE: Know the ASCII code chart

I would recommend memorizing or printing out (and stuffing in your wallet) this chart here: http://en.wikipedia.org/wiki/File:ASCII_Code_Chart-Quick_ref_card.png. Reason being, is you need to covert the ASCII text to numerical binary. The chart linked to gives you the table on how to do it.

Really, you can use any standard ASCII chart that provides you with the decimal, octal or hexadecimal values of the character. So long as you can convert it to binary, that’s all that matters. I like the linked chart above, because it gives it to me out the gate, which is one less conversion to worry about.

STEP TWO: Convert your ASCII string to numerical binary

This is the tedious part. It’s going to take you some time to write down every character in 8-bit binary. I need to stress that you need to write down the FULL 8 BITS, even though the card linked to only gives you 7. So, the 8th bit will always be zero when writing down the full binary word. Here’s a rundown of how you would read the card:

  1. Find the character you wish to convert
  2. Write down 0 + the first three binary bits on the top
  3. Write down the last four binary bits for that letter on the left

So, for example, the text “green” would be “01100111 01110010 01100101 01100101 01101110″. Notice that each binary word is 8 bits, each with leading zeros. This should be the case for EVERY character you write down. Further, the space between letters is NOT ignored. It has the binary value of “00100000″ (“SP” in the chart).

STEP THREE: Pad at the end as necessary with zeros

The total number of bits should be divisible by 6. If it is not, add the necessary zeros at the end until it is. So, for our example of “green”, we have a total of 40 bits, which means we need to add two more zeros to make it divisible by 6 (42 divided by 6 is 7). It’s important that you stop at the first multiple of 6, which means that you should never be adding more than 4 zeros. In fact, you will either be adding two zeros, four zeros, or none at all.

So, for “green” with padded zeros at the end, our binary string becomes: “01100111 01110010 01100101 01100101 01101110 00″

STEP FOUR: Divide your binary string into words of 6 bits

Because our binary string is now divisible by six, we want to make 6-bit words using the same string. So, for “green”, I should end up with 7 total words (because I have 42 bits total in the string). As a result, “01100111 01110010 01100101 01100101 01101110 00″ becomes “011001 110111 001001 100101 011001 010110 111000″

STEP FIVE: Convert your 6-bit words to decimal

Now we need to covert the newly created binary words into decimal. You need to know your binary to pull this off. Thankfully, this isn’t too terribly difficult- you just need to know your powers of 2. So, our string of “011001 110111 001001 100101 011001 010110 111000″ becomes “25 55 9 37 25 22 56″.

STEP SIX: Convert decimal to ASCII

Now, we need to covert our newly calculated decimal numbers to ASCII, and we’ll almost be finished. For this, we’re going to use a different chart than what we started with. We need a chart that will correspond to our values, starting at 0 and ending on 63 (64 possible values, thus the reason it’s called “base-64″).

  1. If the value is between 0 and 25, then the character is uppercase “A-Z” respectfully.
  2. If the value is between 26 and 51, then the character is lowercase “a-z” respectfully.
  3. If the value is between 52 and 61, then the character is the numbers “0-9″ respectfully.
  4. If the value is 62 or 63, then the character is “+” and “/” respectfully.

If that was confusing to you, see the table at http://en.wikipedia.org/wiki/Base64#Examples.

So, for our string of numbers “25 55 9 37 25 22 56″, which came from the text “green”, we see the following come out: “Z3JlZW4″.

STEP SEVEN: Pad the string with “=” as necessary

The last step in your conversion is to pad the string with “=” as necessary, so the total number of your characters is divisible by four. Our base-64 string has only 7 characters, so we must add a “=” at the end to bring the total to 8 characters, which is indeed divisible by four. Thus, we would end up with “Z3JlZW4=” as the final result for “green”.

QUICK EXAMPLE: “Attack at dawn!”

  1. Attack at dawn!
  2. 01000001 01110100 01110100 01100001 01100011 01101011 00100000 01100001 01110100 00100000 01100100 01100001 01110111 01101110 00100001
  3. 010000 010111 010001 110100 011000 010110 001101 101011 001000 000110 000101 110100 001000 000110 010001 100001 011101 110110 111000 100001
  4. No zero padding necessary
  5. 16 23 17 52 24 22 13 43 8 6 5 52 8 6 17 33 29 54 56 33
  6. QXR0YWNrIGF0IGRhd24h
  7. No “=” padding necessary

NOTE:

The base 64 utilities that ship with GNU Coreutils and OpenSSL use a different padding at the end of the encoded string than just equal signs. I haven’t parsed the code yet, so I don’t know why this is, but from what I’m reading online, the standard is to use just “=”, unless I’m missing something. If anyone knows why “K”, “o=” and others show up, I’m all ears. Thanks.

CONCLUSION:

Encoding text to base-64 certainly doesn’t really yield any cryptographic strength, and there exist utilities for doing it on the computer. So, why bother learning it by hand? As stated earlier, it’s a fun skill to have around the house. Combine it with other hand ciphers that you might already know, and you could have a decent algorithm on your hands (pun intended). Heck, let’s see your English teacher decrypt your notes now!