使用openssl解密用Java加密的aes-gcm [英] decrypting aes-gcm encrypted with java using openssl

查看:243
本文介绍了使用openssl解密用Java加密的aes-gcm的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java中具有以下代码:

I have the following code in Java:

public static void deriveKeyAndIV(String password)
            throws Exception
    {
        SecureRandom random = new SecureRandom();
        if (salt == null)
        {
            salt = new byte[HASH_BYTE_SIZE / 8]; // use salt size at least as long as hash
            random.nextBytes(salt);
        }
        if (ivBytes == null)
        {
            ivBytes = new byte[HASH_BYTE_SIZE / 8];
            random.nextBytes(ivBytes);
        }

        PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        keyBytes = skf.generateSecret(spec).getEncoded();
    }
public static byte[] encrypt(byte[] message) 
            throws Exception
    {
        // wrap key data in Key/IV specs to pass to cipher
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        //IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        // create the cipher with the algorithm you choose
        // see javadoc for Cipher class for more info, e.g.
        Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");

        GCMParameterSpec gps = new GCMParameterSpec(128, ivBytes);

        cipher.init(Cipher.ENCRYPT_MODE, key, gps);
        byte[] encrypted = new byte[cipher.getOutputSize(message.length)];
        int enc_len = cipher.update(message, 0, message.length, encrypted, 0);
        enc_len += cipher.doFinal(encrypted, enc_len);
        return encrypted;
    }
public static byte[] decrypt(byte[] cipher_text) 
            throws Exception
    {
        // wrap key data in Key/IV specs to pass to cipher
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        // create the cipher with the algorithm you choose
        // see javadoc for Cipher class for more info, e.g.
        Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");

        GCMParameterSpec gps = new GCMParameterSpec(128, ivBytes);

        cipher.init(Cipher.DECRYPT_MODE, key, gps);
        byte[] decrypted = new byte[cipher.getOutputSize(cipher_text.length)];
        int dec_len = cipher.update(cipher_text, 0, cipher_text.length, decrypted, 0);
        dec_len += cipher.doFinal(decrypted, dec_len);
        return decrypted;
    }
public static void main(String[] args) {
        String pass = "hello";
        try {
            deriveKeyAndIV(pass);
            byte[] tmp = encrypt("world!".getBytes());
            System.out.println(new String(Base64.getEncoder().encode(tmp)));
            System.out.println(new String(tmp));
            System.out.println("encrypted:\t" + bytesToHex(tmp));
            System.out.println("key:\t" + bytesToHex(keyBytes));
            System.out.println("iv:\t" + bytesToHex(ivBytes));
            tmp = decrypt(tmp);

            System.out.println("decrypted:\t" + bytesToHex(tmp));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

示例输出:

5xwfm037nXfGS06V5OKgW/oo6WDuow==
��M��w�KN���[�(�`�
encrypted:  E71C1F9B4DFB9D77C64B4E95E4E2A05BFA28E960EEA3
key:    6D525D38BFF7F70AD25205E97368C197
iv: 060374643557ED8E2F6A215F1B6DBD0E
decrypted:  776F726C6421

我将Base64输出复制到文件(试入)中,并尝试使用以下命令对其进行解密:

I copied the Base64 output into a file (test-in), and tried decrypting it using the following command:

openssl enc -d -base64 -id-aes128-GCM -K 6D525D38BFF7F70AD25205E97368C197  -in ~/Desktop/test-in -out ~/Desktop/test-out -iv 060374643557ED8E2F6A215F1B6DBD0E

我收到了bad decrypt错误消息(退出代码:1).尝试使用不同的模式(id-aes192-GCM和id-aes256-GCM)会得到相同的结果.

I got a bad decrypt error message (exit code: 1). trying different modes (id-aes192-GCM and id-aes256-GCM) resulted the same.

我做错了什么?

推荐答案

我将Base64输出复制到一个文件(试入)中,并尝试使用以下命令对其进行解密...

I copied the Base64 output into a file (test-in), and tried decrypting it using the following command ...

经过身份验证的加密模式在命令行工具中不起作用.从 openssl enc手册页:

Authenticated encryption modes do not work from the command line tools. From the openssl enc man page:

enc程序不支持经过身份验证的加密模式,例如 CCM和GCM.该实用程序不存储或检索身份验证 标签.

The enc program does not support authenticated encryption modes like CCM and GCM. The utility does not store or retrieve the authentication tag.

我知道该文档最近通过上述声明进行了更新(大约在2014年5月或6月).触发它的邮件列表消息是 v1.0.1g命令行gcm错误.

I know the documentation was recently updated (circa May or June 2014) with the statement above. The mailing list message that triggered it was v1.0.1g command line gcm error.

我不知道这些工具的较新版本(例如1.0.2或1.1.0中的openssl enc)是否提供有意义的错误消息,或者您是否只是得到 错误的解密 .

I don't know if newer versions of the tools (like openssl enc in 1.0.2 or 1.1.0) provide a meaningful error message, or if you just get bad decrypt.

我做错了什么?

What I'm doing wrong?

没事.

这篇关于使用openssl解密用Java加密的aes-gcm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆