Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES/CBC/PKCS5Padding encrypt in java decrypt in ruby

Tags:

java

ruby

aes

I am trying to encrypt data in java and decrypt data in ruby.

I found almost same asks, but my case is little bit different.

  • Encrypt in Ruby and Decrypt in Java - Why is it not working?

  • AES/CBC encrypt in Java, decrypt in Ruby

My code is ... Encrypt in java

import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Hex;

class Crypt {
    public static void main(String[] args) throws Exception {
        Map<String, String> node = new HashMap<String, String>();
        node.put("timestamp", "1377499097199");
        JSONObject jsonObject = JSONObject.fromObject(node);
        String json = jsonObject.toString();
        System.out.println(json);

        //key
        String skeyString = "97128424897797a166913557a6f4cc8e";
        byte[] skey = Hex.decodeHex(skeyString.toCharArray());
        System.out.println("key : " + skeyString);

        //iv
        String ivString = "84e8c3ea8859a0e293941d1cb00a39c3";
        byte[] iv = Hex.decodeHex(ivString.toCharArray());
        System.out.println("iv : " + ivString);

        //encrypt
        SecretKeySpec skeySpec1 = new SecretKeySpec(skey, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec1, new IvParameterSpec(iv));
        byte[] encrypted = cipher.doFinal(json.getBytes());
        String encryptedString = Hex.encodeHexString(encrypted);
        System.out.println("=============>");
        System.out.println("encrypted string: " + encryptedString);
        }
}

Result is

{"timestamp":"1377499097199"}
key : 97128424897797a166913557a6f4cc8e
iv : 84e8c3ea8859a0e293941d1cb00a39c3
=============>
encrypted string: 395f6c0e8ad27f57c4a5a8975aa633e5b26f288d37ce18c6971779951f3b3527

and I hope to decrypt (encrypted string) in Ruby

Ruby code is ...(got error)

require 'openssl'

key = "97128424897797a166913557a6f4cc8e"
iv = "84e8c3ea8859a0e293941d1cb00a39c3"
encrypted_string = "395f6c0e8ad27f57c4a5a8975aa633e5b26f288d37ce18c6971779951f3b3527"

de_cipher = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
de_cipher.decrypt
de_cipher.key = key
de_cipher.iv = iv

de_cipher.update(encrypted_string) << de_cipher.final

I expected to get

{"timestamp":"1377499097199"}

But it returns error

`final': bad decrypt (OpenSSL::Cipher::CipherError)

I think the problem is cipher.padding and type of key/iv. But I don't know exactly how to complete ruby code.

Please let me know How to complete this code.

Thank you.

like image 999
blankammo Avatar asked Aug 27 '13 09:08

blankammo


1 Answers

There's two problems with your Ruby code.

First, you're using AES 256 when you should be using AES 128. Java uses AES 128 or 256 based on the size of the key you use, and you're using a 128 bit key.

Second, you need to Hex decode your key, iv, and encrypted_string values in Ruby. OpenSSL Cipher is expecting binary, not hex strings.

require 'openssl';

key = "97128424897797a166913557a6f4cc8e";
iv = "84e8c3ea8859a0e293941d1cb00a39c3";
encrypted_string = "395f6c0e8ad27f57c4a5a8975aa633e5b26f288d37ce18c6971779951f3b3527";

de_cipher = OpenSSL::Cipher::Cipher.new("AES-128-CBC");
de_cipher.decrypt;
de_cipher.key = [key].pack('H*');
de_cipher.iv = [iv].pack('H*');

puts de_cipher.update([encrypted_string].pack('H*')) << de_cipher.final;

Output:

{"timestamp":"1377499097199"}
like image 195
Syon Avatar answered Oct 17 '22 17:10

Syon