Thursday, August 28, 2008

Java Implementation Loader Error in Deploying OpenOffice Add-On Project

My interest has been piqued lately: I am curious about developing applications in the OpenOffice framework, using the OpenOffice SDK.

Anyhow, I had some trouble getting the Add-On project tutorial going. Nothing serious, but I just couldn't deploy the add-on for "Could not create Java implementation loader" errors. Yeah, I didn't have a clue as to what that meant.

But with a bit of googling, I found this thread, which pointed me back to this page on the OpenOffice wiki. The solution is right there, in 2. Possible Work-Arounds. I quote:

This usually happens when one wants to debug Java in the office process and therefore has provided the debug options for Java in the options dialog. The Java service of the extension will be registered in a separate process (uno.exe) which also needs to start Java. This Java uses the same settings from the options dialog.
...
If there is also a Java running in the office process, then the creation of the virtual machine in the second process will fail. The reason is, that the latter receives the same debug settings. It appears that two virtual machines, although in separate processes, cannot use the same port for debugging. If one changes the port number before adding the extension (and after the Java has been created in the office process), then the extension will be installed properly.


Urgh. I installed OpenOffice with its own JRE, but I am using Java SE 6 Update 10 RC as the default environment in my NetBeans IDE (I am also dabbling in JavaFX!). I surmise, however, that when I use the Project View -> Project Node -> Context Menu -> Create OXT | Deploy Office Extension in NetBeans to launch the project deployer, it accordingly uses the environment settings of the NetBeans JRE/JDK the project is using, and not the JRE that comes packaged with OpenOffice.

So, to make a long story short... In WinXP, locate your user's C:\Documents and Settings\%user%\Application Data\OpenOffice.org2, and just delete it. Re-launching/re-deploying the OpenOffice Add-On project will just work. You'll have to change your Windows Explorer settings to display all hidden directories and files.

Mathematicians (nah, I'm not really a mathematician)



Which reminds me of the following joke:
An engineer, a physicist and a mathematician were all staying in a hotel, when each of their rooms individually caught fire. The engineer did some basic math, flooded the floor and said, "It is out." The physicist did more complicated math, used just precisely the amount of water needed to put out the fire and said, "It is out." The mathematician did a lot of complicated math, cried out, "I HAVE SOLVED IT!" and went back to bed.

... think I saw the above joke on /.

Wednesday, August 27, 2008

RSA Encryption: OpenSSL to Ruby to C# (and back to Ruby)

Continuing on the topic of encryption, it turns out that the work project I mentioned in my last post will require transmission of encrypted data from C# to Ruby. As this encrypted data must only be decrypt-able by the Ruby-side logic, asymmetric encryption fits the bill well. Here are some notes on working with RSA public key encryption with OpenSSL to generate the RSA key-pair; Ruby/OpenSSL to extract the public key parameters to feed the C# RSACryptoServiceProvider; C# to use the public key to encrypt an arbitrary array of bytes; and finally back to Ruby/OpenSSL to decrypt the enciphered data with the private key.

Now, I will consider that trust between the C# logic and the Ruby/OpenSSL logic is implied, so there is no need for use of X.509 certificates or what-not to distribute the public key to the C#-side. I will instead use the RSACryptoServiceProvider's FromXmlString method to initialize the provider with the key modulus and exponent. Practically speaking, I would have to obtain the key modulus and exponent (most likely using Ruby/OpenSSL), and then serialize that in an XML form that the C# class RSACryptoServiceProvider understands.

RSA Private Key Generation with OpenSSL
OK, let's start off by first using OpenSSL to generate a 512-bit RSA private key:


... with OpenSSL command-line ...

... generate RSA private key (default of 512-bits)
shino# openssl genrsa -out rsa.priv

... confirm key parameters
shino# openssl rsa -in [rsa.priv] -text -noout

Simple enough, no? And once again, yeah, yeah, yeah: a 512-bit RSA key cannot do much in the way of protecting secrets. Cracked way back in 1999. But let's just agree to go with 512-bits for the sake of this post. BTW, don't forget that you will have to take into account any steps needed to protect this RSA private key file. I leave that exercise to you, dear reader.

Obtain Key Modulus & Exponent Parameters with Ruby/OpenSSL
Next, we use Ruby/OpenSSL to read in our newly-created RSA private key and obtain Base64-encoded string values for key modulus and exponent for the RSACryptoServiceProvider's XML string (we will use those values to calculate the public key in C#-land shortly):

# with irb/ruby/openssl

# use ruby/openssl to load private key
irb(main):001:0> require 'openssl'
=> true
irb(main):002:0> require 'base64'
=> true
irb(main):003:0> privkey = OpenSSL::PKey::RSA.new(File.read('rsa.priv'))

# extract key exponent and Base64-encode
irb(main):004:0> exp = []
=> []
irb(main):005:0> pubkey = privkey.public_key
irb(main):006:0> pubkey.e
=> 65537
irb(main):007:0> (pubkey.e.num_bytes-1).downto(0) {|i| exp << ((pubkey.e >> (i*8)).to_i & 0xFF) }
=> 2
irb(main):008:0> exp
=> [1, 0, 1]
irb(main):009:0> tmp = []
=> []
irb(main):010:0> tmp[0] = exp.map {|b| sprintf("%02x" % b) }.join
=> "010001"
irb(main):011:0> Base64.encode64(tmp.pack('H*')).split("\n").join
=> "AQAB"

# extract key modulus and Base64-encode
irb(main):012:0> pubkey.n
=> 10859685957917547658301583853465231245284761442925449111820039202653087969032
48227098143938496267490334944907126548361037059959257154028677097618826672949
irb(main):013:0> (pubkey.n.num_bytes-1).downto(0) { |i| mod << ((pubkey.n >> (i*8)).to_i & 0xFF) }
=> 63
irb(main):014:0> mod
=> [207, 89, 10, 12, 14, 23, 85, 80, 200, 210, 18, 182, 229, 231, 180, 219, 103,
58, 118, 47, 162, 38, 14, 74, 94, 114, 192, 69, 174, 176, 175, 140, 177,
230, 202, 21, 102, 169, 66, 199, 161, 128, 61, 223, 167, 210, 168, 145, 51,
164, 94, 120, 73, 250, 100, 8, 7, 56, 185, 23, 28, 157, 59, 53]
irb(main):015:0> tmp = []
=> []
irb(main):016:0> tmp[0] = mod.map {|b| sprintf("%02x" % b) }.join
=>"cf590a0c0e175550c8d212b6e5e7b4db673a762fa2260e4a5e72c045aeb0af8cb1e6ca1566a942c7a1803ddfa7d2a89133a45e7849fa64080738b9171c9d3b35"
irb(main):017:0> Base64.encode64(tmp.pack('H*')).split("\n").join
=> "z1kKDA4XVVDI0hK25ee022c6di+iJg5KXnLARa6wr4yx5soVZqlCx6GAPd+n0qiRM6ReeEn6ZAgHOLkXHJ07NQ=="

A good point to bear in mind here is that for Ruby/OpenSSL, the key parameters are instances of OpenSSL::BN, which represent big numbers for OpenSSL for multiprecision integer arithmetics. OpenSSL::BN.num_bytes tells us how many bytes are used to represent a key parameter, and then in order to transform the big number into an array of bytes, we can pass a block that uses a bit mask to obtain the significant bits for each byte of the big number. Then, we transform the byte values in this array into 2-char hexadecimal strings, and concatenate into one, long string of hexadecimal chars. Stuff that into a temporary array, call pack('H*') on the array, remove any line-break chars, and then we Base64-encode the values for modulus and exponent.

Encryption Using RSA Public Key with C#
OK, so we have our 512-bit RSA private key, and we have extracted the key modulus and exponent values as Base64-encoded strings, which we can now pass to C#'s RSACryptoServiceProvider in order to obtain the public key:

using System.Security.Cryptography;
...

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString("
<RSAKeyValue>
<Modulus>
z1kKDA4XVVDI0hK25ee022c6di+iJg5KXnLARa6wr4yx5soVZqlCx6GAPd+n0qiRM6ReeEn6ZAgHOLkXHJ07NQ==
</Modulus>
<Exponent>
AQAB
</Exponent>
</RSAKeyValue>");

Note that the XML string really shouldn't have any line breaks, I only broke it up to for viewing's sake.

The next step is to encrypt some arbitrary data, which we take to be an array of bytes. Be sure to Base64-encode the result, since we will pass that string over to the Ruby/OpenSSL side.

... in C# ...

byte[] cipherbytes = rsa.Encrypt(plainbytes, false);
String ciphertext = Convert.ToBase64String(cipherbytes);

Gotta love C#, the APIs are for the most part crystal clear and user-friendly.

Decrypt Ciphertext with RSA Private Key with Ruby/OpenSSL
Alright, now we just need to bring it all home, and decrypt that ciphertext string with the RSA private key, using Ruby/OpenSSL:

# with irb/ruby/openssl again

# read in private key from file
irb(main):001:0> require 'openssl'
=> true
irb(main):002:0> require 'base64'
=> true
irb(main):003:0> privkey = OpenSSL::PKey::RSA.new(File.read('rsa.priv'))

# Base64 decode the transmitted ciphertext first
irb(main):004:0> ciphertxt = Base64.decode64("RALJTqgPNRcmvZ4E09y4NODl+w/vJPRslmxi8xB9JPSrpDQ
bKjOkoeivTOqL9gT4WBpRpIlqut3jflkcUy/5Qg==")
=> "D\002\311N\250\0175\027&\275\236\004\323\334\2704\340\345\373\017\357$\364l\
226lb\363\020}$\364\253\2444\e*3\244\241\350\257L\352\213\366\004\370X\032Q\244\
211j\272\335\343~Y\034S/\371B"

# decrypt w/ private key
irb(main):005:0> plaintext = privkey.private_decrypt(ciphertxt)
=> "Ru'\035\314`\f\352"

# reconstitute as plain byte array
irb(main):006:0> plaintext.unpack('H*')[0].scan(/../).map{|b|b.hex}
=> #... results in the original array of bytes which we encrypted in C# land!


Conclusion
That wasn't so bad now, was it? We created an RSA private key with OpenSSL, used the Ruby/OpenSSL binding to manipulate the key to extract the key modulus and exponent (the public key material), and fed that into some C# code. This allowed us to encrypt an arbitrary array of bytes with the RSA public key in C#-land, and then we wrapped it up by decrypting the ciphertext with the corresponding RSA private key with Ruby/OpenSSL.

Like I mentioned in my last post, it is the lack of clear documentation for the Ruby/OpenSSL API that can trip you up. However, hackable nature of Ruby made it fairly painless to explore and experiment, and to come up with the above example of RSA asymmetric encryption using OpenSSL, Ruby and C#.

Tuesday, August 26, 2008

DES encryption: Java to OpenSSL to Ruby

Encryption has always been an interest of mine, but I really don't have mad skillz. I must admit that I ran into a bit of difficulty in trying to figure out how to properly use the OpenSSL API for Ruby, but what do you expect? The documentation is frustratingly poor.

In parallel with an ongoing project at work, I took some notes on using DES encryption with Java to generate the proper bits for a DES key; OpenSSL to actually use this key to encrypt some file; and then use Ruby/OpenSSL to decrypt. I know, I know: DES has been cracked for some time now. But this an exercise just to see if I could bring together what little acumen I possess in Java, Ruby, and OpenSSL.

Here's how I did it for DES using the Cipher Block Chain operation mode. Note that the DES key and initialization vector are being passed from Java to OpenSSL to Ruby as a string of hexadecimal char, but in reality we are dealing with bytes.

First, we create a valid DES key and set of initialization vector bytes. From the Federal Information Processing Standards Publication 46-2, the specification for the Data Encryption Standard (DES):

A key consists of 64 binary digits ("O"s or "1"s) of which 56 bits are randomly generated and used directly by the algorithm. The other 8 bits, which are not used by the algorithm, are used for error detection. The 8 error detecting bits are set to make the parity of each 8-bit byte of the key odd, i.e., there is an odd number of "1"s in each 8-bit byte.


We'll use Java and the javax.crypto.KeyGenerator factory to create a valid DES key and initialization vector:

// in Java

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

...

public static void main(String[] args) throws Exception {
// create a DES key
KeyGenerator kg = KeyGenerator.getInstance("DES");
SecretKey key = kg.generateKey();
byte[] keyBytes = key.getEncoded();
StringBuffer sbuf = new StringBuffer();
for (byte b : keyBytes) {
sbuf.append(String.format("%02x", (b & 0xFF)));
}
System.out.println("DES key: " + sbuf);

// create initialization parameter bytes
Cipher nonceCipher = Cipher.getInstance("DES/CBC/PKCS5padding");
nonceCipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[8]));
IvParameterSpec iv = new IvParameterSpec(nonceCipher.doFinal(new byte[8]), 0, 8);
byte[] ivBytes = iv.getIV();
sbuf = new StringBuffer();
for (byte b : ivBytes) {
sbuf.append(String.format("%02x", (b & 0xFF)));
}
System.out.println("IV: " + sbuf);
}


The above Java code will output a string of 8 bytes in hexadecimal for the DES key, and also a string of 8 bytes in hexadecimal for the initialization vector to be used in CBC. We next use this as input for the openssl enc program:

... with OpenSSL command-line ...

shino# openssl des-cbc -e -in plaintext.txt -out encrypted.des-cbc \
-K [java-generated DES key string] -iv [java-generated IV string]


The above OpenSSL command will encrypt the file specified with the -in option, using DES-CBC with the given -K DES key and -iv initialization vector. The values for -K and -iv need to be a string of 8 bytes given in hex. Encrypting the plaintext file plaintext.txt will then result in the output encrypted.des-cbc. By the way, this OpenSSL command is using PKCS5 padding as default.

To decrypt with ruby/OpenSSL was a bit tricky. Like I mentioned earlier, the documentation is very, very poor. Assuming that the DES-CBC encrypted file encrypted.des-cbc exists in our current working directory, we can fire up irb to do the decryption and bring it all home:

# with irb/ruby/openssl

# given key = "838519bcc21fb0a1"
# given iv = "33bc52494428f4b6"
# given plaintext msg = "hello, encryption!\n"

irb(main):001:0> require 'openssl'
=> true
irb(main):002:0> f = File.open('encrypted.des-cbc', 'rb')
=> #<file:encrypted.des-cbc>
irb(main):003:0> data = f.readline
=> ...
irb(main):004:0> f.close
=> nil
irb(main):005:0> decrypt = OpenSSL::Cipher::Cipher.new('des-cbc')
=> #<openssl::cipher::cipher:0x4417d60>
irb(main):006:0> decrypt.decrypt
=> #<openssl::cipher::cipher:0x4417d60>
irb(main):007:0> decrypt.key = "838519bcc21fb0a1".scan(/../).map{|b|b.hex}.pack('c*')
=> "\203\205\031\274\302\037\260\241"
irb(main):008:0> decrypt.iv = "33bc52494428f4b6".scan(/../).map{|b|b.hex}.pack('c*')
=> "3\274RID(\364\266"
irb(main):009:0> decrypt.update(data) + decrypt.final
=> "hello, encryption!\n"


Here, we use irb to open the encrypted file and read in the bytes. Then, we use the ruby/OpenSSL API to create a DES-CBC cipher. The call to Cipher.decrypt sets the cipher to work in decryption mode. We next specify the DES key and IV initialization vector, as well as the string of encrypted chars as binary strings.

# ruby snippet
"838519bcc21fb0a1".scan(/../).map{|b|b.hex}.pack('c*')

In setting the key and iv, we provide a 16-char long string of hexadecimal that represents 8-byte values. The above invocation uses String.scan(/../) to break the hex string into a list of 2-char long chunks. Enumerable.map{ |b| b.hex } then maps each 2-char hex chunk back into its numerical (byte) equivalent. Array.pack('c*') lastly transforms the entire list into a single binary sequence. The documentation for Cipher.key= and Cipher.iv= is none too clear that both APIs expect a binary string. I spent quite a bit of time scratching my head as I was mistakenly passing in the plain-vanilla hexadecimal strings for the key and iv values.

Anyhoo, as you have seen, it is not all that hard to do a round-trip DES-CBC encryption using Java to generate the key and iv; OpenSSL to actually encrypt the plaintext; and ruby/OpenSSL to decrypt.

BTW, this doc page in Japanese was a bit more helpful in pointing me in the right direction.

Monday, August 25, 2008

The Hokkaido Bank predicts 57K JPY increase per household for winter expenses

A article in yesterday's Hokkaido Shimbun Press reports that the Hokkaido Bank expect an increase of 57000 JPY per household of expenditures on gasoline, kerosene, and other expenses related to winter. This figure is based on a recent Hokkaido Bank study that predicts a gross 134.6 billion JPY increase in winter expenditures for the coming 2008 season. To make things worse, this study does not take into account effects of the expected increase for electricity rates.

This seemingly downward spiral is certainly straining things for all people living in Hokkaido. Food, fuel and utilities like electricity all have been rising steadily. Personally, this has been weighing heavily on my mind as of late, as I am contemplating another career jump in order to keep up with all of the price-increases and keep my family afloat.

I never really wanted to believe it, but the IT business here Hokkaido is starting to look very ghetto to me. There are a handful of good people, but most companies are pursuing a very conservative (read that as "weak" if it cannot let their employees stay ahead of inflation!) business plans for systems integration, made-to-order development, or call center and support.

It may have been a mistake to tie myself directly to the local economy, so I am actively looking for opportunities and challenges that are more global and dynamic. Lord knows, there are a tons of such jobs in Tokyo...

Thursday, August 7, 2008

Dan Kaminsky Finally Outlines DNS Vulnerability

Dan Kaminsky finally outlined the DNS vulnerability that was reported about 4 weeks ago (article on The Register). It appears to be a DNS forgery variant of DNS cache poisoning. If an attacker of a DNS server can quickly and correctly guess a 16-bit transaction ID, then the attacker will be able to replace DNS entries with their own spoofed ones. There has been one confirmed attack so far, where the attacker caused AT&T subscribers to be re-routed to fake Google pages.

For the curious, you might want to see how safe your ISP's DNS servers are. Try the "Check My DNS" button on Dan Kaminsky's site; or the "Test My DNS" link here. The key here is to see the amount of randomness of transaction IDs and query source ports in your ISP's DNS servers.

Hacking FasTrak

I've never used the FasTrak debit system for the tollways in California when I lived there, but The Register recently reports that an exploit has been found. I can't believe that FasTrak apparently transmits its unique ID number in the clear.

Not that I use it here, but I wonder what sort of vulnerabilities and countermeasures exist for the Electronic Toll Collection (ETC) system in Japan. Or おサイフケータイ services for the mobile devices used in Japan.

Saturday, August 2, 2008

Installing OpenSolaris on VirtualBox

Finally got around to installing Sun's OpenSolaris on VirtualBox. It turned out to be easier than I expected. Just grab the latest release (2008.05 at the time of this writing), and follow thru the install just as you would any other guest OS on VirtualBox. You can find details for installing OpenSolaris on VirtualBox here and here, but believe me, it is surprisingly sweet and smooth.

The only hitch I had was getting the network interface going. Apparently, OpenSolaris ships with the Network AutoMagic, which sadly is not all that automagical when installing on VirtualBox. But the solution is quite simple. Just keep on reading...

After what should be a successful install, confirm that nwam is running:


# svcs nwam


It will be enabled by default. We don't need this, we need to configure the Intel PRO/1000 MT Desktop (NAT) e1000g0 network adapter interface, and activate it. Let's turn off nwam, and set things up:

# svcadm disable physical:nwam
# svcadm enable physical:default


Next, we configure and activate the e1000g0 connection. In the OpenSolaris' guest window menu, select System > Administration > Network. Select the e1000g0 connection, and click on the Properties button. In the Interface Properties window, check the boxes for Enable this connection and Activate on boot. Select DHCP for Configuration, and click OK. Lastly, click on the Activate button to bring e1000g0 up. You can reboot to complete the process, and hey, whoa!



Network love!

Time to install the JDK, NetBeans, and other tools...