Home > Uncategorized > Using the crypt unit for something useful

Using the crypt unit for something useful

February 14, 2014 Leave a comment Go to comments

Right, I posted the full crypto unit yesterday, but I didn’t have time to post an example of how to use it. So this time we are going to have some real-life practical examples.

How does this key stuff work?

We are all used to passwords and security these days, but there are a few things that have changed since the golden days of home-made services and DIY websites. Most notably is the fact that you should never store passwords at all. If you think back 5-8 years ago, it would have been perfectly valid for a webservice or a database driven website to store usernames and passwords in a database table. But should someone gain access to your database, they could in fact rob your database of passwords and ruin everything.

The solution? Dont store passwords. You store a hash of a password. A hash is just a number that is generated from analysing a piece of data, it’s sometimes also called a checksum. The important part about a hash is that it will generate the same number exclusively when the data matches. As you can imagine, it’s almost impossible to guess a password from a hash-number.

Another thing to note about key-pairs is that they are not designed to encrypt large sections of data. They are designed to encrypt small things (passwords) and have a limit ranging from 256 to 512 bytes – meaning somthing like 128 unicode characters. Encryption of files and streams is done by generating a hash from an encrypted password – and using that hash as the key for a common cipher like RC4 or Blowfish. These extra steps makes it more or less impossible to decode your data without the absolute and concrete original information.

Here is one way of generating a a portable, encrypted file:

  • Generate a hash from a password
  • Generate a cipher key-set
  • Encrypt the hash using the public key
  • Save the encrypted hash to the target-stream
  • Save the public key to the target-stream
  • Encrypt the password-hash using the private key
  • Use encrypted hash as a key-stream for encrypting the “real” data
  • Save encrypted data to the target-stream

This creates a dual-key lock. You need both the original private-key and password to decipher the data. Even if you steal the original key-set or gain the original password, the data remains useless without both. By de-coupling these two factors and only providing the public key, another person can only verify that the file belongs to you (by first generating a hash of your password, then decrypting the provided hash using the public key and comparing it), but you still cant read the content of such a file without the private key. This is more or less how secure document transportation works, where you can checkout a document anywhere in the world with a smart-card and personal password. The private key is stored on the card and without both items the data remains unreadable.

How you chose to play around with these schemes is up to you. In some cases rolling your own security is better than buying a solution, because the less that is known about a scheme – the harder it will be to crack.

Generating keys

To generate a key-pair you would write:

procedure TForm1.Button3Click(Sender: TObject);
var
  mPrivate: TStream;
  mPublic:  TStream;
  mTemp:  String;
begin
  if TCryptoAPI.rsaMakeKeys(mprivate,mPublic) then
  begin
    try
      if TCryptoAPI.rsaKeyToBase64(mPrivate,mTemp) then
      showmessage(mTemp);

      if TCryptoAPI.rsaKeyToBase64(mPublic,mTemp) then
      showmessage(mTemp);
    finally
      mPrivate.Free;
      mPublic.Free;
    end;
  end;
end;

I included two helper functions for turning the streams into Base64 encoded strings, simply called rsaKeyToBase64() and rsaBase64ToKey(), its is sometimes easier to transport the keys as text (and also to display the results while working).

Encrypting a stream

procedure TForm1.Button2Click(Sender: TObject);
var
  mKey: TStringStream;
  mText:  String;
  mSrc: TStringStream;
  mdst: TStringStream;
begin
  //Replace mSrc with your filestream
  mSrc:=TStringStream.Create;
  try
    mDst:=TStringStream.Create;
    try
      if TCryptoAPI.rsaBase64ToKey("Base64 key text here",TStream(mKey)) then
      begin
        try
          //Remove this obviously when encrypting a file or a memory stream
          mSrc.WriteString("Text/data to encrypt here");
          mSrc.Position:=0;

          if not TCryptoAPI.rsaCryptStream(mKey,mSrc,mDst) then
          RaiseLastOSError;
        finally
          mKey.Free;
        end;
      end;
    finally
      mDst.Free;
    end;
  finally
    mSrc.Free;
  end;
end;

To decrypt a stream, do the same as above but call TCryptoAPI.rsaDecryptStream() instead.

Voila! Next we will implement the code for encrypting passwords with the crypto-key-set!

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: