Blog moved.

Blog moved to Octopress on Heroku.

www.kalmbach.com.ar is now pointing to kalmbach.herokuapp.com.

Encrypting data with OpenSSL and ruby (III)

Ok, we saw public-key (or asymmetric) and symmetric-key cryptography. With the first one you have a pair of keys, one of which is public and you can share with your friends in order to exchange info, they can encrypt the data using your public key and only you will be able to decrypt it. Also you can encrypt (sign in) something with your private key, and that can only be decrypt using your public key, which ensures the data came from you (that’s why is called signature).

So, if you encrypts the data with your private-key, and then with your friend’s public key, you will have a safe channel, the data will be signed by you and only your friend will be able to see it. Unfortunately this can only be used with small amounts of data (limited by the size of the key).

On the other side, we have the symmetric-key encryption, that can encrypt large amounts of data without problem, but we cannot send the secret-key by email to our friends, since it could be intercepted or revealed and all will be able to decrypt the data. If only there was a way to share this small secret-key with your friend.. oh wait.

Yes! we can combine both methods to share information. (Pretty Good Privacy)
Using the public-key encryption to share our symmetric-key, and then the symmetric-key to encrypt the data. Finally you send the encrypted data with the encrypted and signed symmetric key.

require 'openssl'

# This is our secret
data = File.read('a-lot-of-secrets.txt')

# Create a RSA key (public-key) of 2048 bits
rsa_key = OpenSSL::PKey::RSA.new (2048) 

# Extract the public key
public_key = rsa_key.public_key.export

# Send my public key to my friend
# Get his public key and store it
friend_key = share_public_key(public_key)

# Create AES cipher, (symmetric-key) of 128 bits
aes_cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
aes_cipher.encrypt
key = aes_cipher.random_key
iv  = aes_cipher.random_iv

# sign the key
signed_key = rsa_key.private_encrypt(key)
signed_iv  = rsa_key.private_encrypt(iv)

# encrypt keys with friend's key
friends_rsa_key = OpenSSL::PKey::RSA.new(friend_key)
encrypted_key = friends_rsa_key.public_encrypt(signed_key)
encrypted_iv  = friends_rsa_key.public_encrypt(signed_iv)

# send to friend the encrypted_key + encrypted_iv
# He will decrypt first with his private key, and then with our public key.

# now that we securely shared the symmetric key encryption, 
# we can send him the encrypted data
encrypted_data = aes_cipher.update(data) + aes_cipher.final

Encrypting data with OpenSSL and ruby (II)

We already saw how to encrypt small amounts of data, like credit cards, web forms or signatures with public-key encryption. Today we will see how to encrypt large amounts of data using symmetric-key encryption. Symmetric-key algorithms are a class of algorithms for cryptography that use the same cryptographic key for both operations, encryption and decryption of data, for this reason the key must remain secret.

OpenSSL supports a large variety of symmetric-key algorithms, a list of the supported algorithms can be obtained with:

OpenSSL::Cipher.ciphers

To create a Cipher instance you need to know 3 things, the name of the algorithm, the length of the key in bits and the cipher mode to be used. The most generic way to create a new Cipher object is like this:

name = 'AES'
bits = '128'
mode = 'CBC'

cipher = OpenSSL::Cipher.new("#{name}-#{bits}-#{mode}")

The string parameter must be all in uppercase or all in lowercase.
Each algorithm has also a class defined under the Cipher namespace that you can use to obtain an instance of that algorithm:

cipher = OpenSSL::Cipher::AES.new(128, 'CBC')

For symmetric algorithms, encryption and decryption are very similar operations, and you can do both with your Cipher instance. However you need to set the instance with the operation you intend to do with it. This is done calling encrypt or decrypt on the instance without parameters:

cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
cipher.encrypt

decipher = OpenSSL::Cipher::AES.new(128, 'CBC')
decipher.decrypt

After obtaining the instance of the Cipher and setting the operation, we need to set the key to be used. The cipher instance provides a way to generate a random and more secure key than a plain and simple password. The cipher modes CBC, CFB, OFB and CTR all need an initialization vector, IV for short, if not explicity set, OpenSSL will default the IV to all-zeroez. The cipher instance also provides a way to create a secure random IV. In brief, you will need a key and an initialization vector:

cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
cipher.encrypt

key = cipher.random_key
iv  = cipher.random_iv

Warning
ECB and CBC are both block-based modes, unlike the streaming-based modes, they operate on fixed-size blocks of data, and therefore they require a finalization (padding) to decrypt the last block of data. For that reason you need to add the content of #final to the encryption/decryption buffer or you will end up with errors or truncated data.

Finally, all said, we can encrypt and decrypt some data:

plain_data = "My secret is that there is no secret"
cipher = OpenSSL::Cipher::AES.new(128, 'CBC')

cipher.encrypt
key = cipher.random_key
iv  = cipher.random_iv

encrypted_data = cipher.update(plain_data) + cipher.final

cipher.decrypt
cipher.key = key
cipher.iv = iv

plain_data = cipher.update(encrypted_data) + cipher.final

Encrypting data with OpenSSL and ruby

Hi, today’s tip is about protecting data with encryption, we will use public-key cryptography, this allow us to encrypt data using a key public, that you can give your friends or to your mother or to your clients. They can encrypt the data that they want to send you or you want to keep secure, and only you can decrypt it with your private key, the private key must remain in secret to yourself and you can protect it with a passphrase.

Warning
The method that will be described here only allows the encryption of a small amount of data. To be precise, you cannot encrypt anything larger than the key size minus 11 bytes of padding. If you will use a 2048 bit key size, you will be able to encrypt upto (2048 bits / 8) bytes – 11 bytes = 245 bytes of data.

You can use this, for example, to encrypt data in a web form, and store them secured. So you can provide the client side with a public key, and later only you will be able to retrieve or decrypt that data on the server side using the private key. This can be usefull to capture and send sensitive data through the internet.

Ok, to do this, we first need to generate our keys. We will use openssl because I had a bad experience using gpgme on ruby, especially when I needed it to encrypt a large number of items, the gpg context was crashing without any explanation. I reported the bug to gpgme.

The private key is protected by a password, you can provide your own password or generate a random one with ruby:

> require 'openssl'
 => true 
> OpenSSL::Digest::SHA1.hexdigest("#{Time.now}")
 => "fc97f3c09daa072b4699d3ebb0b287ed22589f37"

To generate the keys with openssl we will use the unix command line:

$ openssl genrsa -des3 -out private-key.pem 2048
Generating RSA private key, 2048 bit long modulus
............+++
............+++
Enter pass phrase for private-key.pem:
Verifying - Enter pass phrase for private-key.pem:

Now we will extract the public key from the private key:

$ openssl rsa -in private-key.pem -out public-key.pem -outform PEM -pubout
Enter pass phrase for private-key.pem:
writing RSA key

Now that we have the keys, we can encrypt data with the following ruby code:

require 'openssl'

public_key = File.read('public-key.pem')
plain_data = 'My secret is the color blue'

key = OpenSSL::PKey::RSA.new(public_key)
encrypted_data = key.public_encrypt(plain_data)

The encrypted_data is binary data, so if you want to send in the body of an email or as part of a json request, you will need to convert it to a Base64 string:

require 'base64'
string = Base64.encode64(encrypted_data)

Ok, now, the encrypted data is only useful if we can decrypt it, that will be done with, assuming the data encrypted is Base64 encoded:

require 'openssl'
require 'base64'

private_key = File.read('private-key.pem')
password = 'fc97f3c09daa072b4699d3ebb0b287ed22589f37'
encrypted_data = 
"kGll3oEEtHGavEaMVdlHJMZ4qvjEntV1D9uMoOHk+uLkmdK84enDte3Rvxtw9vdA
2mUwjc/V2Mvib7lFeZBvhYLtg0pCGu15qdOVH5I7PmyjM6xnF9YQC0ceBawxkPxX
UJWhGUp9HxTW1rmUun/mgBK6iOjOcoCF1Ggmkx7SnJOxqrU6P69pHA=="

key = OpenSSL::PKey::RSA.new(private_key, password)
plain_data = key.private_decrypt(Base64.decode64(encrypted_data))

As we mentioned above, this will only allow us to encrypt small amounts of data, to encrypt more data we will need symmetric-key encryption. You can then use the public-key encryption to protect your symmetric-key.

We will see symmetric-key encryption with ruby in another post.

Ordinalize numbers in current locale

Hi, today’s tip is about how to ordinalize numbers in current locale, ActiveSupport by default ordinalize the numbers in english, if we want to translate these values to the current locale language we may need to extend ActiveSupport.

After googling a little I found this post that solves the issue, here is my implementation based on that approach. 

The ordinalize method is implemented on the ActiveSupport::Inflector module, so we will override that method, Rails provides a place where you can put these overrides, in config/initializers/inflections.rb. Since it is a script executed during the initialization of Rails, you will need to restart the server to use this method.

Here is the config/initializer/inflections.rb file:

module ActiveSupport
  module Inflector
    def ordinalize(number)
      abs_number = number.to_i.abs
      rules = I18n.t 'number.ordinals', :default => ""
      
      # Assume English for compat
      rules = {
        :'\A\d{0,}(11|12|13)\z' => "%dth",        
        :'\A\d{0,}1\z'  => "%dst",
        :'\A\d{0,}2\z'  => "%dnd",
        :'\A\d{0,}3\z'  => "%drd",
        : other => "%dth"
      } if rules.empty?    

      match = rules.find do |rule|        
        Regexp.new(rule[0].to_s).match(abs_number.to_s)        
      end      
      
      match = match && match[1] || rules[:other]
      
      match % number
    end
  end
end

After adding the override, if we try to ordinalize numbers in other locales we will still get the default english ordinal value. To make our code work, we need to specify how to ordinalize the numbers in other locales, this is done in the config/locales/*.yml files.

For example, to ordinalize numbers in Spanish(Argentina), we modify the file config/locales/es-AR.yml.

es-AR:
  number:    
    ordinals:
      \A{0,}(1|3)\z:   "%dro"
      \A{0,}2\z:       "%ddo"
      \A{0,}(4|5|6)\z: "%dto"
      \A{0,}(7|0)\z:   "%dmo"
      \A{0,}8\z:       "%dvo"
      \A{0,}9\z:       "%dno"
      other: "%d"

There you go, to test this in rails console, you can do:

1.9.2p320 :001 > I18n.locale = 'es-AR'
 => "es-AR" 
1.9.2p320 :002 > (1..20).each {|x| puts x.ordinalize }
1ro
2do
3ro
4to
5to
6to
7mo
8vo
9no
10mo
11ro
12do
13ro
14to
15to
16to
17mo
18vo
19no
20mo
 => 1..20

Hope you can find this piece of code useful.

Rake task sugar for Sequel Migrations

To apply Sequel migrations you generally run Sequel’s migrator with

bin/sequel -m

But if you need to run your migrations on a remote environment, like Heroku, a rake task will make this operation be more handy.

Copy and paste this gist on your Rakefile and you will be able to run migrations, rollback migrations, reset database and get the current schema version of the database.

Sample Usage

To get the schema version

# rake db:version

To apply all the available migrations

# rake db:migrate

To rollback the last migration, remember to pass the target version, the migrator will undo the migrations until the schema version is equal to the target version.

# rake db:version
Schema Version: 56
# rake db:rollback[55]

If you don’t pass any target version to the rollback rake task,
it will rollback all migrations, leaving the database on schema version 0.

To reset database, just run

# rake db:reset

Here is the code for the rake task.
https://gist.github.com/4471560

namespace :db do
  require "sequel"
  Sequel.extension :migration
  DB = Sequel.connect(ENV['DATABASE_URL'])
  
  desc "Prints current schema version"
  task :version do    
    version = if DB.tables.include?(:schema_info)
      DB[:schema_info].first[:version]
    end || 0
 
    puts "Schema Version: #{version}"
  end
 
  desc "Perform migration up to latest migration available"
  task :migrate do
    Sequel::Migrator.run(DB, "migrations")
    Rake::Task['db:version'].execute
  end
    
  desc "Perform rollback to specified target or full rollback as default"
  task :rollback, :target do |t, args|
    args.with_defaults(:target => 0)
 
    Sequel::Migrator.run(DB, "migrations", :target => args[:target].to_i)
    Rake::Task['db:version'].execute
  end
 
  desc "Perform migration reset (full rollback and migration)"
  task :reset do
    Sequel::Migrator.run(DB, "migrations", :target => 0)
    Sequel::Migrator.run(DB, "migrations")
    Rake::Task['db:version'].execute
  end    
end

Rack and Roll – An Introduction to Rack

A ruby web server interface

Rack provides an interface between web servers and web applications. A formal way of communication between both parts. This does possible the ruby web ecosystem, where all the rack clients (web apps, web frameworks, middleware) are compatible with any of the rack servers (thin, webrick, unicorn, etc) without having to change anything, you just need to stack them up.

The specification is quite simple, it wraps the HTTP requests and responses into a single method call.

Rack specification => rack.rubyforge.org/doc/SPEC.html

Rack applications

A Rack application is an ruby object that responds to call. It takes one argument, a Hash of CGI-like headers containing details from the HTTP request, and it returns a tuple with three values: the status, the header and the body.

The simplest form of a Rack application could be something like this:

require 'rack'

class MyApp

# We need an object that responds to call
# and accepts one argument
  def call(req)
    # We need to return a tuple with 3 values: status, header and body
    # The status must be an HTTP status as Integer
    # The header must be a hash of key/values, it should declare the content type
    # The body needs to responde to .each and it must yield String values
    [200, {'Content-Type' => 'text/plain'}, ['Hello Rack World!']]
  end
end

# Use rack handlers to run the app, I will use Thin web server
# We need an object, that's why we create an instance of the class
Rack::Handler::Thin.run MyApp.new, :Port => 3000

Save it as myapp.rb, run it with

ruby myapp.rb

Open a web browser at localhost:3000 and you should see our nice greeting message. Now as an exercise change the message to req.inspect, stop the application and re-launch it, go to the browser and refresh the page, you will be able to see all the request details passed to our app through the argument.

Using this info you can respond to only specific requests, respond with a 404 status to those ones you don’t support. For example, we will respond nicely only to requests to the root path “/”.

require 'rack'

class MyApp

  def call(req)
    case req['PATH_INFO']
    when '/'
      [200, {'Content-Type' => 'text/plain'}, ["Hello World"]]
    else
      [404, {'Content-Type' => 'text/plain'}, ["404 Page not found."]]
    end
  end
end

Rack::Handler::Thin.run MyApp.new, :Port => 3000

Is getting better, now we can add a “/datetime” resource that will return the date and time.

  when "/datetime"
  [
    200,
    {'Content-Type' => 'text/plain'},
    [Time.now.strftime("%A, %d  %B, %Y %H:%M:%S %z %Z")]
  ]

rackup

rackup is a useful tool for running Rack applications. In order to run our app with this tool, we need to create a config.ru file using the Rack::Builder DSL

require rack
require ./myapp

run MyApp.new

Drop the last line from the myapp.rb file

Rack::Handler::Thin.run MyApp.new, :Port => 3000

and now you can run your app from the command line like this

rackup

Conclusion

These examples are very straightforward, just like the Rack protocol. The power of rack resides on his simplicity. The point of this post is illustrate that you don’t need a full web framework like Rails to build a nice and simple web site, you just need to implement the Rack interface, or you can use a microframework, like Sinatra or Cuba. We will cover these on the future.

end.

Tagged ,

How to verify the Http-Compression of Static-Content

I know this can be done with Fiddler or Firebug, but i wanted something more faster and simpler, and also it was a perfect excuse for writing my first ruby script. You pass the url, the port, and the path to the element you want to check, and you are done.

Sample run against http://www.ioactive.com/affiliateImg.js

./IsCompressed.rb www.ioactive.com 80 /affiliateImg.js

  WebSite: www.ioactive.com:80
  Path: /affiliateImg.js

  Compression: NO,	1217 bytes,	message: OK ,	code: 200

And the code:

#!/usr/bin/env ruby

require 'net/http'

if ARGV.length != 3
  puts "Mode of Use: script [WebSite] [Port] [Path]"
  exit 1
end

website = ARGV[0]
port = ARGV[1]
path = ARGV[2]

puts "\n"
puts "\tWebSite: " + ARGV[0] + ":" + ARGV[1]
puts "\tPath: " + ARGV[2]
puts "\n"

begin
  http = Net::HTTP.new(website, port)
  resp, data = http.get(path, {'Accept-Encoding' => 'gzip, deflate'})

  encoding = resp.response['content-encoding']
  if encoding.nil? 
    encoding = 'NO'
  end

  puts "\tCompression: "+ encoding + ",\t" + data.size.to_s + " bytes,\tmessage: "+ resp.message + ",\tcode: " + resp.code
  puts "\n"
rescue Exception => detail
  puts "An error ocurred. Execution aborted."
  puts detail.message
end
Tagged

Single Instance Applications

Hello! Here ‘s a fairly simple example of how to create single instance Applications with LibUnique and Gtk +. I took the example in the documentation and changed it to demonstrate how to pass a parameter to the active instance.

How to compile:

gcc -o uniquesample uniquesample.c 
  `pkg-config --cflags gtk+-2.0 unique-1.0 --libs gtk+-2.0 unique-1.0`

How to run it, first launch first instance:

# ./uniquesample

Then, launch the others:

# ./uniquesample "One App to rule them All"

Here’s the code:

#include gtk/gtk.h
#include unique/unique.h

static UniqueResponse 
message_received_cb (UniqueApp *app, 
                     UniqueCommand command, 
                     UniqueMessageData *message, 
                     guint time_, 
                     gpointer user_data)
{
  UniqueResponse res;

  /* get text payload from the unique message data*/
  gchar *texto = unique_message_data_get_text (message);
	
  /* Get the label widget */
  GtkLabel *label = GTK_LABEL (user_data);

  switch (command)
  {		
    case UNIQUE_ACTIVATE:
      {
        gtk_label_set_text (GTK_LABEL (label), texto);
        res = UNIQUE_RESPONSE_OK;
        break;
      }
    default:
      res = UNIQUE_RESPONSE_OK;
      break;
  }

  return res;
}

static gboolean 
delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
{
  gtk_main_quit ();
}

int
main (int argc, char *argv[])
{
  gtk_init (&argc, &argv);

  /* Create the UniqueApp Instance */
  UniqueApp *app = unique_app_new ("home.myapp", NULL);
	
  /* check if there already is an instance running */
  if (unique_app_is_running (app))
  {		
    if (argc > 1)
    {						
      /* build a message with the first command line argument */
      UniqueMessageData *message = unique_message_data_new();
      unique_message_data_set_text (message, argv[1], -1);
	
      /* send the message, we don't care about the response */
      unique_app_send_message (app, UNIQUE_ACTIVATE, message);

      unique_message_data_free (message);		
      g_object_unref (app);
    }
  }
  else
  {
    /* this is the first instance */
    GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);	
    GtkWidget *label = gtk_label_new ("UNIQUE INSTANCE");

    /* Makes app "watch" a window. 
     * Every watched window will receive startup notification changes automatically
     */
    unique_app_watch_window (app, GTK_WINDOW (window));

    /* connect to the signal so we can handle commands and responses
     * We are passing the label widget here as user data */
    g_signal_connect (G_OBJECT (app), "message-received", 
                      G_CALLBACK (message_received_cb), label);

    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event_cb), NULL);

    gtk_widget_set_size_request (GTK_WIDGET (window), 300, 200);
		
    gtk_container_add (GTK_CONTAINER (window), label);	
    gtk_widget_show_all(window);

    gtk_main ();

    g_object_unref (app);
  }

  return 0;
}

Gtk+ 3.0 Client Side Theme

How to override user’s theme or I want my app with green buttons.

#include 

static gboolean
delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
	gtk_main_quit();
}

int
main (int argc, char* argv[])
{
  gtk_init(&argc, &argv);

  GtkCssProvider *provider = gtk_css_provider_new ();

  gtk_css_provider_load_from_data (
    provider, 
    "GtkButton {font: Monospace 10; background-color: rgba(0%, 76%, 0%, 0.6);}", 
    -1, NULL);

  GdkDisplay *display = gdk_display_get_default ();
  GdkScreen *screen = gdk_display_get_default_screen (display);

  gtk_style_context_add_provider_for_screen (
    screen, GTK_STYLE_PROVIDER (provider),
    GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
  
  g_object_unref (provider);

  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL);

  GtkWidget *button = gtk_button_new_with_label("GtkCssProvider load from data");
  gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (button));
  gtk_widget_show_all (GTK_WIDGET (window));

  gtk_main ();	
  return 0;
}
Follow

Get every new post delivered to your Inbox.

Join 58 other followers