July 12, 2011

How to sign stuff and then verify it using PKCS7

You'd think security is about obfuscation when trying to find resources on how to do stuff. We end up with people not really knowing how to implement security and implement it wrongly.
I might be one of those people so be warned, but if you need to a resource to get started at least, you can look here. So let's begin.

What we're doing is creating a pair of X509 keys; a private key and a public key. Both keys will be stored in a file called a keystore file. This file exists on your computer and is unlocked by a password. Once the file is unlocked, you need to unlock the key as well, so two passwords are needed, unless you use the same password for both.

You can use the private key to sign data and public key to verify the signature. Here's what I think happens during the process.

1. Sign some data using the private.
2. Optionally include the public key and data in the signature so that it can be verified.
3. Send the signature to the recipient.
4. Recipient verifies the data in the signature
5. Recipient verifies the signature with the certificate containing the Public key shared earlier.
6. If both 4 and 5 are verified correct, then the data can be considered to the signed.

Here's some code using the free bouncy castle library for Java.

Here we open the keyfile and unlock it using the keyfile password.


KeyStore keystore = KeyStore.getInstance("jks");
InputStream input = new FileInputStream("c:\\keyfile.jks");
try {
keystore.load(input, password);
} catch (IOException e) {
}


Now we get the private key for the key pair that we have in the keystore. The keypair is identified by an alias. Again we use the password to unlock the private key.

    PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, password.toCharArray());



Next we get the Certificate for the key pair to include in the signature. The certificate is not protected by a password. This means its OK to share it with others. It's not ok to share the Private key as it will enable others to sign stuff on your behalf.

    Certificate cert = keystore.getCertificate(alias);


Here is the signing code. First we add the provider to the Security Manager. It will then be reference using the provider code "BC". We create a data generator, initialize it with a signer, wrap our data in a content wrapper and finally generate the signature based on the content, and the "BC" security provider.


// Create the provider
Security.addProvider(new BouncyCastleProvider());
// Create a generator
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
// initialize the signer
generator.addSigner(privateKey, (X509Certificate) cert, CMSSignedDataGenerator.DIGEST_SHA1);
// turn our data into content
byte[] data = "ABC123".getBytes();
CMSProcessable content = new CMSProcessableByteArray(data);
// sign the data
CMSSignedData signedData = generator.generate(content, true, "BC")



The results gets put into bytes and sent out. You probably want to encode it somewhat using BASE64. I'll leave that to you.

    byte[] result = signedData.getEncoded();


That's it for signing. Now what about verification of the signature. Remember that we will share the certificate containing the Public key with the recipient - probably ahead of time. If not you need to verify the credentials within the certificate. This will probably involve a Certificate authority. If the certificate was exchanged securely the CA should not be an issue.

Next comes the data and the signature. We receive the signature as an array of bytes and we wrap it.

    CMSSignedData s = new CMSSignedData(result);


We extract the public key from the keystore in the usual way. But this would be the keystore of the recipient. It would not have the private key.

    PublicKey publicKey = cert.getPublicKey();


We can extract the content from the signature in this way. Notice its an array of bytes so, re-encode it in ASCII or other format. This covers step 4 above. I will not go into details of how to verify it. For me, it was sufficient to print it out and verify it was indeed what I signed in the first place.

    byte[] signedContent = (byte[]) s.getSignedContent().getContent();



Now we verify. We iterate the list of signers, and ensure one of the signers is the party we expect. If verified returns true for at least one signer, that's ok for us. Your rules for verification may be different. For example, it may need to be signed by three people or at least two out of three.

    java.util.Iterator i = signers.getSigners().iterator();
while ( i.hasNext()) {
SignerInformation signer = (SignerInformation) i.next();
verified = signer.verify(publicKey, "BC");
}


That's it. Take it for what you paid for it. Nothing.

January 30, 2009

MobileXT for Nokia 5800 XM

Here's what you need to know to get Garmin working for Nokia 5800 XM.
The guides I found suck. It took a long time to get things working.

1. Get the latest version of Garmin MobileXT. Doesn't matter where you get it from. Because its gonna be locked.

2. Install it. The installer is basically an unzipper and it unzips to a removable drive - that means your phone. So on your phone there will be a Garmin folder. There should be an MobileXT icon. If not look for the SIS file to install.

3. You need your IMEI. On the Nokia 5800 XM, key this in *#06# your imei appears. This is whats used to tie the app to your phone so its used to generate the product code.

4. You need a couple programs. First one converts your IMEI to a unit ID. Second one converts your unit ID to an unlock code. Once you have the unlock code - write it into a text file named SW.UNL This is the application unlock file. Copy this to the Garmin folder.

5. You need VirtualKey because your phone is a touch screen and lacks the hardware keys required to control the app. Virtual key remaps hardware keys to other hardware keys. The nokia 5800 has at least 4 hardware keys and these need to be remapped to YES/NO UP and DOWN. Go find a config file which already does the mapping. Copy it into the Virtual Key private folder and off you go. Getting VirtualKey to work is another exercise but the other guides cover this sufficiently.

6. Now run VirtualKey. Put it in the background. Then run MobileXT. It should be unlocked - if you followed all the steps. Hey you're done. Oh yea you should load a map into the garmin folder.

December 03, 2008

Useful Tip of the day #1

Here's how to generate W3C time format from XSL using an Java enabled XSLT parser.

Step 1. create four variables


<xsl:variable name="s1" select="java:format(java:java.text.SimpleDateFormat.new('yyyy-MM-dd'),java:java.util.Date.new())"/>

<xsl:variable name="s2" select="java:format(java:java.text.SimpleDateFormat.new('HH:mm:ssZ'), java:java.util.Date.new())" />

<xsl:variable name="s3" select="substring($s2,1,11)" />

<xsl:variable name="s4" select="substring($s2,12)" />



Step 2. Concatenate variables s1,s3,s4 and include a T and a colon (:)

<xsl:value-of select="$s1"/>T<xsl:value-of select="$s3"/>:<xsl:value-of select="$s4"/>


This will yield: 2008-12-04T11:05:35+08:00
Which is kinda like the W3C format without the milliseconds.

August 19, 2008

Installing XP from a USB drive

I searched this on Google and found a few guides which listed 15 steps in 3 parts. How about we make it less daunting?

Step 1. CHECKLIST - Assuming you already have a PC here is what you need: A windows XP Install CD and a 1GB USB drive

Step 2. DOWNLOAD - this and unzip it.

Step 3. FORMAT - Run usb_prep8.cmd from the usb_prep8 folder. Use default options to format your USB drive. Keep the DOS box open. Its a script which runs step 5.

Step 4. INITIALIZE - the boot sector by running "bootsect.exe /nt52 R:" from the bootsect folder. Replace R: with the drive letter of your USB disk.

Step 5. SETUP - Go back to the DOS box. There is a menu here. Set up items 1-3. Then run 4.

Step 6. SELECT - YES YES YES! You're done, your USB disk is ready. Plug it into your PC and install XP.

April 03, 2008

Sometimes you can't binary

Lately I've messed around with EBCDIC and ASCII. So I've got my head around the concept of encoding and sometimes its useful to encode data from one format into another. Now lets say you need to encode something in Base64.
Here are some pointers:
In .NET
Dim buf() As Byte
Dim strResult as String
buf = System.Text.ASCIIEncoding.ASCII.GetBytes("Some text")
Convert.ToBase64String(buf)
buf = Convert.FromBase64String(strResult)

In Java (Go here)
Get Base64Coder.java
String s;
s = Base64Coder.encodeString("some text");
s = Base64Coder.decodeString(s);

To verify, decode the encoded output from .NET in Java and vice-versa.

February 28, 2008

XBus Enterprise Application Integration

Here's my primer on XBus which is an open source Enterprise Application Integration framework available on sourceforge.

What is it?

It's a framework (set of tools) which allows data (text, xml, byte streams) to be translated, processed, and routed from one system to another (database, AS400, Web Service) using a variety of protocols (HTTP, File, JDBC, FTP).

Can you give me an example?

Let's say you need to go to a FTP site and download a bunch of account numbers and dump it into a database everyday. You could hire a programmer to write a program to do it. He would choose his favorite language (probably a scripting language like ruby or perl) then create a cron job to run the script. It would take him 1 day to do it. His code would not be very maintainable except by himself.

With xBus, and armed with some xml parsing and transformation tools, you could create an xBus system by defining routing rules in several config file. It would take you half a day to do it and it would be very maintainable - involving no new code.

Are you kidding me?

Maybe.

Break it down for me

You have config files which are named standard_whatever.conf. It has to start with standard and it has to end with .conf. Inside the config file you have your base definitions. This includes the setup for Trace (logging), Journaling (more logging), Error Handling (Error logging) and other system parameters. You can have more config files, which are also read and appended to each other. Just make sure you don't define the same thing twice. Each entry in the config file contains a key and value. Each key is categorized by three parts - namely chapter, section and key.

To create a process you need to some systems. All systems get data from someplace such as files, HTTP connections, FTP or other systems). If the system gets data from an external source, its called a receiver. Some systems sends data somewhere else. If the system sends data to an external sink, its called a sender. So the most basic process is one receiver, one sender and one routing instruction.

To define a system, several configuration entries are needed, according to the type of system. For example for a FileReceiver, you need to define the filename, the type of message and what to do with the file if there is an error, if the file is empty, etc.

To define a routing instruction (which is sequential in nature) You need to define the routing strategy. This can be either Invoke, Distribute or both. With Invoke, the message is sent and the response and acknowledgment is required. With Distribute only the acknowledgment is required.

How do you run a process

There are two ways to run a process. The first is to run it manually. A simple command is issued from the console. It can be linked to a scheduled task/cron job. The second way, which is required for certain Receivers is to add it to a servlet engine or a background service. This is required if you're polling a folder, or listening to a socket, or accepting HTTP requests. So they way to run your process depends on what your first system is.

Is that all?

No. There's more. But this is a primer, not a user's guide. There's lots more but this should help you wrap your head around the concepts. There are other features such as XSL transformations, Java Message Queues for asynchronous processing, Tomcat integration etc. Good luck.

February 27, 2008

EBCDIC and Packed Decimal on AS400

Last week I connected to an AS400 system. What we were doing was sending requests and reading the responses. Connecting, sending and receiving was not a problem because the AS400 system communicated using TCP/IP sockets. So a simple .NET component did all the work. What was difficult was figuring out the message formats without much official documentation.

Here's a primer on digital data. All digital data is stored in a binary digit or bit - that is 0's and 1's. It gets tiresome to read 0's and 1's so we group 8 binary digits into a byte. To view things on your computer screen, these bytes are then translated to characters using an encoding. The most common encoding is ASCII, which converts a byte to a character. ASCII is used in a lot of modern operating systems including MAC, UNIX, LINUX and Windows. Later people discovered that a byte which could represent a number between 0 and 256 was not enough to encode all available characters including arabic, chinese, hebrew and other characters. So they came up with unicode where each character is represented by 2 bytes.

An earlier encoding - which predates ASCII is EBCDIC. It too encodes a character in 1 byte but the mapping is all switched around. So writing a program in .NET which uses ASCII to write a message in EBCDIC is the challenge we will address in this post.

From the AS400 system, we were able to get the trace log which shows the communication going between the client and the AS400 system. This is what we needed to reverse engineer the message format. However the communication traveling between the two systems is encoded in EBCDIC and viewing it in an ASCII browser only led to gibberish. Certainly there are EBCDIC editors available, some are free and some you need to pay for. But what is curious about the message being transmitted is that some of it is EBCDIC some of it is still binary data in the form of a binary coded decimal (more on that later).

So the first problem is reading the data transmitted. For this I recommend a HEX editor/viewer. There are HEX viewers with a variety of features and functions which will allow you to do the job much easier. But this blog is not about doing it the easy way. This blog is about doing it without needing to pay any money. So download any hex viewer. I used Notepad++ which is a free portable app. There is also Hex Editor NEO from HDD software.

Make sure you have the binary data alone - in a file and open it with the hex editor. Now you have a bunch of numbers, characters, dots, squares, funny characters, and umlauts. It's a table. On the far left is the address of the row. On the top is the address of the column. So add those two and you have the address of the byte. The byte is the two hex-digit entry you see separated by spaces. On the far right is the encoding of the byte probably in ASCII. More expensive hex editors allow you to change the encoding to EBCDIC.

Each byte is represented by 2 4-bit hex-digits. A hex-digit is a number between 0 and 15, where A represents 10, B represents 11 and so forth. A hex digit is also known as a nibble (half a byte - get it?) Is that clear? It gets confusing at this point so re-read the whole paragraph again if you must.

So two nibbles = 1 byte. Two hex-digits make 1 byte. 00 = 0 and FF = 255. Got it? I'm sorry a 10-year IT professional needs to write this primer. High-level programming doesn't really delve into this topic much. I remember when I was a high school student taking extra classes in computers learning about punch cards. Computers didn't have keyboards or hard disks. Just punch card readers and punch cards. See Apu's doctoral thesis blackjack program on punch-cards.

So these bytes convert to EBCDIC. But how? Lacking a nice hex editor which can convert bytes to EBCDIC, you need a mapping table. Unfortunately there are a few flavors of EBCDIC so try to find one that matches.



Here is one I lifted off this website.

Now you know how to do it manually. Here is how you can do it in .NET. There is no EBCDIC encoder in the .NET System library. There is however an API for encoder classes. So just find an encoder class which is freely available. This is the one I used written by Jon Skeet from Reading, England. Sample code is on the page.

So that's settled. All that's left is to write some byte array manipulation code and to watch your indexes. The next problem is that the message format also contains some Packed Decimals. This is also known as Binary Coded decimals. Here's a primer to that.

To code a number in ASCII you would need 1 byte per digit. This is wasteful because you only need 10 values to code a digit when a byte gives you 256 values. Remember our nibbles? Recap: a nibble is 4-bits - or half a byte -represented by a hex-digit.

A hex digit has 16 values. So if we code a decimal digit in a hex digit we only waste 6 values and not 246 values. Here's another way to look at it, we can represent 100 values (0-99) in a byte using the binary coded decimal representation versus only 10 values in the ASCII representation. Here's what a binary coded decimal looks like: 0 = 0x00, 1 = 0x01, 10 = 0x10, 20 = 0x20, 99 = 0x99.

Hang on... why not just code a number using the entire byte - leaving you with 256 values per byte. Certainly this is the most compact way? I don't know. Perhaps it more operation extensive to convert the bytes to a number if coded that way because it involves multiplication operations. From what I've read of BCD (which isn't much - this is the encoding) with a few more notes.

1. The sign (negative or positive) is encoded as the last nibble. I forget but its like F and C for positive. D for negative.

2. If the nibbles are odd number - including the sign, pad with a zero in front. That is if you have a 6 digit BCD (999999 in decimal) its BCD representation is 9 99 99 9F. Notice the first byte is missing one hex-digit so just pad it with a zero 0x0999999F.

3. I'm not sure how decimal places work but I suspect a decimal point location is agreed upon by both sender and receiver. So the BCD value is then divided by powers of 10.

There - now you know all there is to know.