AES ECB模式在java中加密并在ruby中解密

时间:2013-12-28 06:53:24

标签: java ruby-on-rails encryption cryptography aes

我必须使用java编写的加密方法。我的加密java代码:

public static String encrypt(String content, String sKey) {
  try {
    SecretKey secretKey = null;
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
    secureRandom.setSeed(sKey.getBytes());
    kgen.init(128, secureRandom);
    secretKey = kgen.generateKey();
    byte[] enCodeFormat = secretKey.getEncoded();
    SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, key);

    byte[] byteContent = content.getBytes("utf-8");
    byte[] result = cipher.doFinal(byteContent);

    return ByteUtil.parseByte2HexStr(result);
  } catch (Exception e) {
    e.printStackTrace();
  }
  return content;
}


## ByteUtil.java
...
public static String parseByte2HexStr(byte buf[]) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < buf.length; i++) {
        String hex = Integer.toHexString(buf[i] & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        sb.append(hex.toUpperCase());
    }
    return sb.toString();
}

我的ruby解密代码(不能正常工作):

require "openssl"
require 'digest/sha2'
require 'base64'

def decryption(encrypted, key)
  decipher = OpenSSL::Cipher::AES.new(128, :ECB)
  decipher.decrypt
  decipher.padding = 0
  decipher.key = [key].pack('H*')

  encrypted = [encrypted].pack('H*')
  plain = decipher.update(encrypted) + decipher.final

  p plain
  p plain.unpack('s*')
  p plain.unpack('m*')
  p plain.unpack('u*')
  p plain.unpack('h*')
  p plain.unpack('a*')
end

任何人都可以提供帮助?提前谢谢!!!

当我使用'ef3192c8803a47cb829d487dd2f78a3d'作为密钥,并使用我的java代码加密'helloworld'时,我得到'3CAEF382FB17A045EADDEFC72D3D0362',但是当我尝试使用我的ruby代码解密它时,我打电话

decryption('3CAEF382FB17A045EADDEFC72D3D0362', 'ef3192c8803a47cb829d487dd2f78a3d')

我无法获得'helloworld',所以我认为解密代码不起作用。

Java解密代码(可行)

public static String decrypt(String content, String sKey) {
    try {
        SecretKey secretKey = null;
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(sKey.getBytes());
        kgen.init(128, secureRandom);
        secretKey = kgen.generateKey();

        byte[] data = ByteUtil.parseHexStr2Byte(content);
        byte[] enCodeFormat = secretKey.getEncoded();

        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] result = cipher.doFinal(data);
        return new String(result, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return content;
}

2 个答案:

答案 0 :(得分:3)

Java实现有点混乱。

用于在java代码中加密的实际AES密钥是使用SecretKey secretKey作为输入使用以下代码生成的String sKey

    SecretKey secretKey = null;
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
    secureRandom.setSeed(sKey.getBytes());
    kgen.init(128, secureRandom);
    secretKey = kgen.generateKey();
    byte[] enCodeFormat = secretKey.getEncoded();

为了能够在 ruby​​ 代码中解密,您需要SecretKey secretKey的内容。尝试在上面的代码后添加此跟踪语句:

    System.out.println("Key: " + ByteUtil.parseByte2HexStr(enCodeFormat));

并将其用作 ruby​​ 电话中的密钥。

答案 1 :(得分:1)

你没有在两端使用相同的密钥。在Java加密中,您使用密钥作为随机数生成器的种子,然后使用 的输出作为密钥。在Ruby方面,您直接使用输入值作为键。