Ruby & Java Crypto interoperability

A

Andy Akins

Well, I've taken a couple days to look at it - googled for solutions
- and I'm still scratching my head. So, time to ask the mailing list :)

I apologize ahead of time for including some Java code below - I hope
it doesn't offend anyone :)

I have a legacy Java project - that isn't going away. But I'm looking
to write some scripts that manipulate some of the information that
the legacy system produces. And I'm just learning Ruby...

My problem is this - the project involves encrypted data. That is,
the Java system uses the javax.crypto libraries to encrypt/decrypt
some of the data using Blowfish. So I'm trying to use the
OpenSSL::Cipher module to decrypt data that has been encrypted via
Java - and it isn't working.

Attached are two files. The first is a Java test framework - it
creates a Key and a IV, then Base64 encodes them and saves them to a
file. Then, it uses the Key and IV to both encrypt and decrypt a
string. The encrypted string is written to another file, again
encoded to Base64.

The second file is a poor attempt to write a Ruby decrypter. I am
well aware that my code is probably not very ruby-ish...I am fairly
new, coming from Java, and haven't picked up the idioms yet.

All of the System.out.println's and puts's are to show what the
various systems are producting - and it appears that they are truly
using the same keys, ivs, and crypttext. But when the ruby program is
run, I get:

/testcrypt.rb:30:in `final': bad decrypt (OpenSSL::CipherError)
from ./testcrypt.rb:30

I have tested the OpenSSL module using the sample code - it works.
Its just trying to decrypt the Java code.

Any help from anyone would be greatly appreciated - both in trying to
get the Crypto code to work, but also in correcting any of my poor-
ish ruby code.

Thanks!

Andy Akins


testcrypt.rb:
=========================================
#! /usr/bin/ruby

require "Base64"
require "openssl"

text = ''

puts 'Testing encryption'
keyfile = open("paams.key")
keyline = keyfile.gets
ivline = keyfile.gets
keyfile.close
key = Base64.decode64(keyline)
iv = Base64.decode64(ivline)
puts "- Attempting Decryption"
puts " Decoded key: #{key}"
puts " Decoded iv: #{iv}"
puts " Encoded key: #{keyline}"
puts " Encoded iv: #{ivline}"

open("encrypted.txt") { |infile|
text = infile.gets
}

puts " Encrypted text: #{Base64.decode64(text)}"
puts " Encoded text: #{text}"
cipher = OpenSSL::Cipher::Cipher.new( "BF-CBC" )
cipher.decrypt(key,iv)
output = cipher.update(Base64.decode64(text))
output << cipher.final
puts output
=========================================
Encrypter.java:
=========================================
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.Cipher;
import java.io.PrintWriter;
import java.io.FileOutputStream;
import java.io.BufferedReader;
import java.io.FileReader;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

public class Encrypter {

public void run() {
try {
System.out.println("Encryption Tester");
makeKey();
encrypt();
decrypt();
} catch (Exception e) {
e.printStackTrace();
}
}

public void makeKey() throws Exception {
PrintWriter writer = new PrintWriter(new FileOutputStream
("paams.key"));
byte [] key;
byte [] iv = {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40};
System.out.println("- Making a key...");
KeyGenerator kgen = KeyGenerator.getInstance("Blowfish");
kgen.init(56);
BASE64Encoder encoder = new BASE64Encoder();
key = kgen.generateKey().getEncoded();
writer.println(encoder.encode(key));
writer.println(encoder.encode(iv));
System.out.println(" Decoded key: "+new String(key));
System.out.println(" Decoded iv: "+new String(iv));
System.out.println(" Encoded key: "+encoder.encode(key));
System.out.println(" Encoded iv: "+encoder.encode(iv));
writer.close();
System.out.println(" Done.");
}
public void encrypt() throws Exception {
System.out.println("- Encrypting data...");
PrintWriter writer = new PrintWriter(new FileOutputStream
("encrypted.txt"));
BufferedReader reader = new BufferedReader(new FileReader
("paams.key"));
BASE64Encoder encoder = new BASE64Encoder();
BASE64Decoder decoder = new BASE64Decoder();
String keyline = reader.readLine();
String ivline = reader.readLine();
byte [] key = decoder.decodeBuffer(keyline);
byte [] iv = decoder.decodeBuffer(ivline);
byte [] result;
System.out.println(" Decoded key: "+new String(key));
System.out.println(" Decoded iv: "+new String(iv));
System.out.println(" Encoded key: "+keyline);
System.out.println(" Encoded iv: "+ivline);
reader.close();
SecretKeySpec skey = new SecretKeySpec(key,"Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
IvParameterSpec ivs = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, skey, ivs);
result = cipher.doFinal("Test String".getBytes());
System.out.println(" Encrypted text: " + new String(result));
System.out.println(" Encoded text: " + encoder.encode
(result));
writer.println(encoder.encode(result));
writer.close();
System.out.println(" Done.");
}

public void decrypt() throws Exception {
System.out.println("- Decrypting data...");
String result;
BufferedReader reader = new BufferedReader(new FileReader
("paams.key"));
BASE64Decoder decoder = new BASE64Decoder();
String keyline = reader.readLine();
String ivline = reader.readLine();
String encrypted;
byte [] key = decoder.decodeBuffer(keyline);
byte [] iv = decoder.decodeBuffer(ivline);
System.out.println(" Decoded key: "+new String(key));
System.out.println(" Decoded iv: "+new String(iv));
System.out.println(" Encoded key: "+keyline);
System.out.println(" Encoded iv: "+ivline);
SecretKeySpec skey = new SecretKeySpec(key,"Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
IvParameterSpec ivs = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, skey, ivs);
reader = new BufferedReader(new FileReader("encrypted.txt"));
encrypted = reader.readLine();
result = new String(cipher.doFinal(decoder.decodeBuffer
(encrypted)));
System.out.println(" Encrypted text: " + new String
(decoder.decodeBuffer(encrypted)));
System.out.println(" Encoded text: " + encrypted);
if (result.equals("Test String"))
System.out.println(" Successful.");
else
System.out.println(" Failed!");
}

public static void main(String [] args) {
Encrypter enc = new Encrypter();
enc.run();
}
}
 
R

roland.schmitt

Andy Akins schrieb:
....
cipher = OpenSSL::Cipher::Cipher.new( "BF-CBC" )
cipher.decrypt(key,iv)
output = cipher.update(Base64.decode64(text))
output << cipher.final
puts output
=========================================
....

Hi, sorry for the late reply, but im in holidays for the last weeks.

Change your ruby script to:

cipher = OpenSSL::Cipher::Cipher.new( "BF-CBC" )
#cipher.decrypt(key,iv)

cipher.key_len=7
cipher.key = key
cipher.iv = iv
output = cipher.update(Base64.decode64(text))
output << cipher.final()

I think Blowfish works with a 128 bit key per default and your key is
only 56 bit.

Hope this help,
Roland
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top