Search code examples
javarubycryptographyblowfish

Java's SecretKeySpec in Ruby?


I'm trying to port over some Java code to Ruby. I was given a class that uses several classes in Java's crypto package (javax.crypto.*) in order to encrypt a string using Blowfish. There are several parts that I'm stuck on and would love some help.

public String encrypt(String var1) throws BlowfishCipher.BCException {
    try {
        byte[] var2 = var1.getBytes("UTF-8");
        byte[] var3 = this.encrypt(var2);
        return bytesToHexString(var3);
    } catch (Exception var4) {
        if(var4 instanceof RuntimeException) {
            throw (RuntimeException)var4;
        } else if(var4 instanceof BlowfishCipher.BCException) {
            throw (BlowfishCipher.BCException)var4;
        } else {
            throw new BlowfishCipher.BCException(var4);
        }
    }
}

public byte[] encrypt(byte[] var1) throws BlowfishCipher.BCException {
    try {
        Cipher var2 = Cipher.getInstance("Blowfish");
        byte[] var3 = hexStringToBytes(this.sKey);
        SecretKeySpec var4 = new SecretKeySpec(var3, "Blowfish");
        var2.init(1, var4);
        return var2.doFinal(var1);
    } catch (Exception var5) {
        if(var5 instanceof RuntimeException) {
            throw (RuntimeException)var5;
        } else {
            throw new BlowfishCipher.BCException(var5);
        }
    }
}

private static String bytesToHexString(byte[] var0) {
    StringBuffer var1 = new StringBuffer();

    for(int var2 = 0; var2 < var0.length; ++var2) {
        String var3 = Integer.toHexString(255 & var0[var2]);
        if(var3.length() < 2) {
            var1.append("0");
        }

        var1.append(Integer.toHexString(255 & var0[var2]));
    }

    return var1.toString();
}

Again, I can do most of it in Ruby, but the thing that I'm missing is the SecretKeySpec. Is there an equivalent in Ruby?

My code in Ruby looks something like this. The difference is that the Cipher I'm newing up is blowfish instead of bf-ecb

OpenSSL::Cipher.new('blowfish').encrypt

I also set my own key_length because the key that I'm supposed to be using is 14 characters.


Solution

  • The Java code seems to hex decode the key first. The SecretKeySpec is just a wrapper around the (random or pseudo-random) bytes of the key.

    So you first need to decode the hexadecimal string and then use that as key:

    cipher = OpenSSL::Cipher.new('blowfish-xxx-ecb')
    cipher.encrypt
    cipher.key = [sKey].pack('H*')
    return cipher.update(var1) + decipher.final
    

    Where xxx is the size in bits of the decoded key.