Asymmetric Encryption - Revisited (in PyCrypto)

02.23.2014 12:33 by kbeckman | Comments

A few months ago, I presented a lightning talk at the monthly Nashville Ruby MeetUp giving an example of asymmetric encryption using the Ruby wrapper for OpenSSL. Today was the first day of the PyTennessee conference in Nashville and I wanted to see if I could translate the example and fill a slot in the lightning talks session. Here goes.

An Example with PyCrypto…

In the eye of the eye Python developer, the following might be a little rough… Before the code below, the only other experience I’ve had with the Python language was earlier today when I was successfully able to print the phrase “Hello, World” to the console output.

 

import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Hash import MD5

# Use a larger key length in practice...
KEY_LENGTH = 1024  # Key size (in bits)
random_gen = Random.new().read

# Generate RSA private/public key pairs for both parties...
keypair_snowden = RSA.generate(KEY_LENGTH, random_gen)
keypair_pytn    = RSA.generate(KEY_LENGTH, random_gen)

# Public key export for exchange between parties...
pubkey_snowden  = keypair_snowden.publickey()
pubkey_pytn     = keypair_pytn.publickey()

# Plain text messages...
message_to_snowden  = 'You are a patriot!'
message_to_pytn     = "Russia is really nice this time of year...\nUse encryption and make the NSA CPUs churn and burn!"

# Generate digital signatures using private keys...
hash_of_snowden_message = MD5.new(message_to_snowden).digest()
signature_pytn          = keypair_pytn.sign(hash_of_snowden_message, '')
hash_of_pytn_message    = MD5.new(message_to_pytn).digest()
signature_snowden       = keypair_snowden.sign(hash_of_pytn_message, '')

# Encrypt messages using the other party's public key...
encrypted_for_snowden   = pubkey_snowden.encrypt(message_to_snowden, 32)    #from PyTN
encrypted_for_pytn      = pubkey_pytn.encrypt(message_to_pytn, 32)          #from Snowden

# Decrypt messages using own private keys...
decrypted_snowden   = keypair_snowden.decrypt(encrypted_for_snowden)
decrypted_pytn      = keypair_pytn.decrypt(encrypted_for_pytn)

# Signature validation and console output...
hash_snowden_decrypted = MD5.new(decrypted_snowden).digest()
if pubkey_pytn.verify(hash_snowden_decrypted, signature_pytn):
    print "Edward Snowden received from PyTn:"
    print decrypted_snowden
    print ""

hash_pytn_decrypted = MD5.new(decrypted_pytn).digest()
if pubkey_snowden.verify(hash_pytn_decrypted, signature_snowden):
   print "PyTN received from Edward Snowden:"
   print decrypted_pytn

Resources

Ruby LDAP Membership Query

01.20.2014 15:15 by kbeckman | Comments

Omniauth is easily one of the most often used Ruby gems in my toolset. Recently, I needed to use an Omniauth plugin that I haven’t used before – omniauth-ldap. Getting omniauth-ldap setup and configured was relatively straightforward; and as advertised, it provided authentication via LDAP query against the organization’s domain controller.

 

Unfortunately (and a bit unexpectedly) though, the contents of the Omniauth authentication hash didn’t contain a list of groups the user belonged to – a requirement for our authentication strategy. The applications I’m working need to translate a given user’s LDAP group membership(s) into application roles for authorization purposes. So as it turns out, after the initial LDAP call for authentication (via omniauth-ldap), I needed to make an additional query against the LDAP provider to get a list of the user’s memberships to parse and convert to application roles.

 

Here’s the short Ruby shell script I whipped up to test making an additional LDAP query for user memberships before I built a few classes and actually integrated it into the application. The @ldap_settings[:auth] hash are the account details used to connect and issue the LDAP query. The values of @ldap_settings and @base will change for your environment (I removed the actual values in this example).

 

#!/usr/bin/env ruby

require 'net/ldap'
require 'pry'

class MembershipQuery

  def initialize
    @ldap_settings = {
        :host => 'ldap-server',
        :auth => {
            :method   => :simple,
            :username => 'CN=Ldap Auth,OU=Authentication,OU=Service Accounts,DC=YOURDOMAIN',
            :password => 'password'
        }
    }

    @base = 'DC=YOURDOMAIN'
  end

  def query(username)
    result  = nil
    ldap    = Net::LDAP.new(@ldap_settings)
    filter  = "(&(objectClass=user)(sAMAccountName=#{username}))"

    if ldap.bind

      ldap.search(:base => @base, :filter => filter) do |object|
        result = object.memberof
      end
    else
      raise 'Authentication Error!'
    end

    result
  end

end

puts MembershipQuery.new().query('Ric_Flair')

A Quick Intro to OpenSSL Asymmetric Encryption

10.03.2013 05:16 by kbeckman | Comments

This post is my summary of the lightning talk for tonight’s Ruby Meetup in Nashville. I should have known that I’d need a bit more than five minutes to cover an intro to OpenSSL asymmetric encryption… Thank goodness for blogs! In the spirit of a lightning talk, I’ll keep this short an cover only the high-level points of this topic.

 

A Quick Primer…

Asymmetric cryptography is important in a number of applications and protocols that we use every day and it’s beneficial for software developers to know at least a little bit about the topic. Let’s start with a quick definition… Asymmetric cryptography is a type of cryptographic algorithm that utilizes private/public key pairs for encrypting data. In simplistic terms, data encrypted with a public key may only be decrypted with its corresponding private key and data signed with a private key can be verified with its corresponding public key.

 

One important use for asymmetric cryptography is for the generation of “digital signatures”. Digital signatures are useful for verifying the identity behind an email message or authentication token (SAML tokens anyone?). Digital signatures are also used to verify the authenticity of software packages. To generate a digital signature, an entity will generate an encrypted hash [serving as the “signature”] based on a digest algorithm (message digest) and some message content (i.e. an email message) using their private key. The message is then sent to a third party along with its digital signature. To verify authenticity of the original message, a third party verifies the encrypted signature hash by using the sender’s public key to decrypt the signature hash and compares the decrypted contents with its own hash of the original message content. If the message hashes match, the message is said to be authentic. If the hashes do not match, the message has been tampered with in some way before it was received.

 

Taking this a step further, asymmetric cryptography is also used to encrypt the contents of messages. Building on the example above, two parties can send secure messages to each other provided that they first share their public keys. Party X can secure a message for Party Y by encrypting a message using Party Y’s public key. Since the only key able to decrypt the data is Party Y’s private key, the message is unreadable to anyone other than Party Y.

 

Unfortunately, asymmetric encryption is an extremely slow method of encryption – much slower than symmetric encryption algorithms that use a single key (i.e Advanced Encryption Standard or AES). Web browsers use a combination of asymmetric and symmetric encryption to enforce the SSL/TLS protocols for secure web sites. In this scenario, the web server and browser use asymmetric encryption negotiate a secure key using the website’s SSL certificate and client machine’s security certificate. The negotiated message/key is then used as the encryption key for continued communication using faster symmetric encryption.

The Code…

This code snippet is a trivial example whereas a single Ruby shell script simulates secure communication between the Nashville Ruby Meetup Group and our favorite patriot, Edward Snowden.  The script generates an RSA private/public key pair for each party; exports the public key (to provide to the other party); encrypts a message for each party using the other’s public key; and decrypts the message using each party’s own private key. Additionally, I added message signing and verification to this snippet (although it was not part of my original lightning talk code sample).

 

#!/usr/bin/env ruby

require 'openssl'

KEY_LENGTH      = 4096  # Key size (in bits)
digest_fuction  = OpenSSL::Digest::SHA256.new # Predetermined signature digest function


# Generate RSA private/public key pairs for both parties...
keypair_snowden = OpenSSL::PKey::RSA.new(KEY_LENGTH)
keypair_meetup  = OpenSSL::PKey::RSA.new(KEY_LENGTH)

# Public key export for exchange between parties...
pubkey_snowden  = OpenSSL::PKey::RSA.new(keypair_snowden.public_key.to_der)
pubkey_meetup   = OpenSSL::PKey::RSA.new(keypair_meetup.public_key.to_der)

# Plain text messages...
message_to_snowden  = 'You are a patriot!'
message_to_meetup   = "Russia is really nice this time of year...\nUse encryption and make the NSA CPUs churn and burn!"

# Generate digital signatures using private keys...
signature_meetup  = keypair_meetup.sign(digest_fuction, message_to_snowden)
signature_snowden = keypair_snowden.sign(digest_fuction, message_to_meetup)

# Encrypt messages using the other party's public key...
encrypted_for_snowden = pubkey_snowden.public_encrypt(message_to_snowden) #from Meetup
encrypted_for_meetup  = pubkey_meetup.public_encrypt(message_to_meetup)   #from Snowden

# Decrypt messages using own private keys...
decrypted_snowden = keypair_snowden.private_decrypt(encrypted_for_snowden)
decrypted_meetup  = keypair_meetup.private_decrypt(encrypted_for_meetup)


# Signature validation and console output...
if pubkey_meetup.verify(digest_fuction, signature_meetup, decrypted_snowden)
  puts "Edward Snowden received from Ruby Meetup:"
  puts "\"#{message_to_snowden}\"\n\n"
end

if pubkey_snowden.verify(digest_fuction, signature_snowden, decrypted_meetup)
  puts "Ruby Meetup received from Edward Snowden:"
  puts "\"#{message_to_meetup}\""
end

Why is this Important?

I’m sure by this point, you’re no stranger to the countless news reports of  domestic NSA spying. The NSA is capable of seeing  just about everything on the Internet including your personal emails regardless of constitutionality or legality. There are also a large number of American organizations, who either by their own will or by NSA influence, provide the NSA with what is essentially an open, unencrypted pipeline to all of your online data. These organizations bypass encryption or provide your data before it has the chance to be encrypted. If that doesn’t scare you, it should… The only way you can ensure the security of your data and your messages is to encrypt that data personally before it’s transmitted over the wire. …and the intent of this post was to show you how that can be done. There’s no guarantee that the NSA won’t eventually be able to decrypt the encrypted messages you send. However, you can and should slow them down a bit by making their servers work a lot harder to get at your personal information. I’m an honest, law-abiding citizen who pays taxes every April 15th and will do so until the day I die. If the NSA choses to read my personal emails to my wife, invoices I send to my clients or anything else that’s either none of their business or NOT a threat to the national security of the United States, then they’re going to have to waste some CPU cycles doing so.

 

One Last Comment…

Check out GPG Tools. It’s an open-source encryption suite that plugs in to Apple Mail allowing you to sign and encrypt emails using asymmetric encryption. It allows you to create keys with a maximum of 4096 bits and according to the algorithm estimates on keylength.com, there’s a good chance it would take the NSA a while to crack your encryption.

Fight Back Against Pseudo-Security

09.11.2012 13:27 by kbeckman | Comments

At least some of your online personal and financial information is AT RISK RIGHT NOW. Some of your information might already be compromised… Even worse, some of the companies hosting your information may not even know that a breach has occurred. And worst of all, your personal information might be IS in the hands of companies with  bullshit security practices.  Online security breaches are an increasingly common occurrence… Back in June, LinkedIn was hacked and 6 million of its users’ passwords were posted online – mine was one that was stolen… A month or so later, Yahoo! was hacked and 400,000 user accounts were compromised. Today, well-known hosting service and DNS registrar – GoDaddy – was hacked and the number of affected sites is in the millions. Although a leak of passwords or personal information may or may not have been part of the breach… Folks, those are just the major instances this summer.

 

Amidst all the web chaos today, I became aware of the half-assed, don’t-give-a-shit security considerations of my former web hosting vendor – Arvixe. Here are the details…

 

Arvixe Billing Users Beware!!!

Until a couple of weeks ago, coding4streetcred.com was hosted through web hosting vendor, Arvixe.  The hosting arrangement was extremely vanilla – just a single server configuration sharing an IIS instance with who-knows-how-many other sites. Arvixe’s pricing was reasonable and the initial setup was incredibly easy. In the two years coding4streetcred.com resided on their servers, I only had a couple of issues with the IIS integration of Microsoft’s WebDeploy utility (probably only because WebDeploy wasn’t a mature product yet). Their support team was awesome and I always got a quick and relevant response. Despite my satisfaction with Arvixe, I recently decided to move my site to Amazon’s Elastic Compute Cloud for a couple of reasons: a) Amazon’s free usage tier; and b) I wanted more experience with Amazon’s Web Services platform for my current and upcoming development contracts.

 

All in all, my experience with Arvixe was good until today when I received the following email from their support team as I attempted to close out my account…

Hello Keith,
I am sorry to hear that you have moved your hosting services to another provider. I can close your account [account name removed] for you, effective immediately. I'll just need you to confirm your identity by providing the last 4 characters of your billing password. If you need to reset your password, please go to [link removed].

ARE YOU SHITTING ME?! PROVIDE THE LAST 4 CHARACTERS OF MY PASSWORD?! For the first time in the history of my Internet usage, a company has asked me to verify my identity by providing details of my actual account password… Unbelievable! After I politely replied via email and tweeted about my disgust with their plain text password storage, I got the following response via Twitter (full conversation is included).

image  image

I finally reset my password to finish the account termination only to find that Arvixe actually sends plain text reset passwords through email! This was another first for me – plain text passwords through email… If you use Arvixe, STOP USING THEM IMMEDIATELY.

 

Why Would This Be a Problem?

Any time you find that all or part of your password information is stored in plain text, IT IS A BIG PROBLEM. The cryptographic details are outside the scope of this post, but I’ll tell you this…

  • Passwords stored in plain text are accessible by anyone (in this case Arvixe employees) who has access to the system database.
  • Passwords stored in plain text are available in plain text to anyone who compromises or hacks that system.
  • Passwords stored in partial plain text can provide enough information to hackers to break the encryption cipher used encrypt the rest of your password. 
  • Passwords sent via email in plain text are only as secure as your email provider’s security. Passwords should never be sent via email – NEVER. An appropriate approach is to send a secure link that allows you to reset your password through some application utility.

It’s no joke… Even worse, this concerned Arvixe’s billing system – the same system that is capable of storing credit card information allowing you to automatically renew your hosting account as needed. Thank goodness they didn’t have any of my credit card information stored. At least not to my knowledge anyway.

 

The Minimum You Should Be Doing to Protect Yourself

The sad truth here is that there are droves of clever hackers out there that can and will break into a system where your account information is stored. The companies hosting your information won’t be able to stop them every time… Fortunately, there are a few things you can do to limit your attack surface… I’ve listed them below in order of what I think are most important.

  • Use a different password for every online account. This sounds a lot more difficult than it actually is… There are several good password management services out there for free or a small fee that can help you with this. I use LastPass. It integrates with every browser and they have mobile apps so you can use them on your Android or iOS devices. A different password for every account minimizes the effect on other accounts if one is ever breached.
  • Don’t store credit card details online. Most sites don’t require you to store credit card details. The exceptions would be those sites that require it for recurring charges… Only do it when or if you have to.
  • Max out your password strength. Every site has different rules regarding password strength (i.e. password length, upper/lower case character requirements, special characters, etc.). Use the longest password with the most numbers, special characters and combination of upper/lower case characters that the site will allow.
  • Be wary of passwords in plain text. If you ever find that your account provider stores passwords in plain text (or even part of your password), terminate your account immediately. The same goes for account providers that send passwords in plain text via email.
  • Make half-assed security practices public. Tweet it. Blog about it. Tell your friends. Other people need to know too… With a little exposure to bad press, companies might actually make it a priority to change their ways.
  • Always be vigilant about your personal details. Your financial stability, credit score, free time and countless other details of your life depend on it…

 

In Closing…

Cyber security is nothing to ignore. If your personal or financial information is online, it is at risk somewhere. There are countless ways your information can get into malicious hands. Unfortunately, it is just an ugly detail of Internet usage. Do everything you can to protect yourself… Stay safe out there.