【问题标题】:decrypt text using the encryption key使用加密密钥解密文本
【发布时间】:2014-10-24 13:49:27
【问题描述】:

我写了一个类来用 AES 加密一个字符串:

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.*;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.util.encoders.Hex;

public class CipherAES {

    public static void brutToHexa(byte[] t) {
        byte[] tab = Hex.encode(t);
        System.out.print("secret key : ");
        for (int i = 0; i < tab.length; i++) {
            System.out.print((char) tab[i] + "");
        }
        System.out.println();
    }

    public static byte[] encrypter(final String message, SecretKey cle)
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, cle);
        byte[] donnees = message.getBytes();

        return cipher.doFinal(donnees);
    }

    public static String decrypter(final byte[] donnees, SecretKey cle)
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, cle);

        return new String(cipher.doFinal(donnees));
    }

    public static void main(String[] args) {

        final String message = "Java is the best";

        KeyGenerator keyGen;
        try {
            keyGen = KeyGenerator.getInstance("AES");
            SecretKey cle = keyGen.generateKey();
            brutToHexa(cle.getEncoded());

            byte[] enc = encrypter(message, cle);
            System.out.print("encrypted text : ");
            System.out.println(DatatypeConverter.printBase64Binary(enc));

            String dec = decrypter(enc, cle);
            System.out.println("decrypted text : " + dec);

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
                IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
    }
}

我以 HEX 格式显示密钥和使用 Base64 编码加密的文本。 要运行,我得到:

secret key : dfaa3b49adbc546d4437107b6a666cb1
encrypted text : iwEjj0Gahfzgq4BWrdY9odNX9PqvHgppz9YZ3mddQq8=
decrypted text : Java is the best

这里是类解密:

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

public class DecryptCipherAES {

    public static void main(String[] args) {
        try {
            byte[] key = ("dfaa3b49adbc546d4437107b6a666cb1").getBytes();
            SecretKey secretKey = new SecretKeySpec(key, "AES");

            String base64String = "iwEjj0Gahfzgq4BWrdY9odNX9PqvHgppz9YZ3mddQq8=";
            byte[] enc = org.apache.commons.codec.binary.Base64.decodeBase64(base64String.getBytes());

            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            String dec = new String(cipher.doFinal(enc));
            System.out.println("texte decrypte : " + dec);

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
    }
}

运行时,我得到这个异常: javax.crypto.BadPaddingException:给定最终块未正确填充

【问题讨论】:

  • 我不认为解密密钥是正确的,因为你已经显示转换为十六进制,可能是错误的想法,这正是我跳出来的原因
  • 我已经检查过了,当我转换十六进制时,我得到相同的字节键。或者提交我可以检查密钥的完整性?
  • 我运行你的代码,将cle.getEncoded() 值传递给DecryptCipherAES(我合并了代码),它工作正常。您需要手动将密钥String“解开”回byte[],我认为您不能简单地依赖使用String#getBytes

标签: java aes padding


【解决方案1】:

核心问题是您假设使用String#getBytes 会将基于十六进制的String 正确转换为字节数组。

您需要手动将十六进制 String 值转换为 byte 数组。想想看,你把一个byte数组转成String格式,还得再转回来。

这基本上是你的代码,但我把你的DecryptCipherAES 放到了decryptWith 方法中。

该示例将密钥和消息都转换为十六进制 String,然后将其传递给 decryptWith,然后将其转换回 byte 数组(通过取消十六进制)。

同样,您也可以使用 base64 编码,但您仍然需要在另一端对其进行解码

import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;
import javax.xml.bind.DatatypeConverter;

public class Test11 {

    public static String brutToHexa(byte[] t) {
        StringBuilder sb = new StringBuilder(t.length * 2);
        for (int i = 0; i < t.length; i++) {

            int v = t[i] & 0xff;
            if (v < 16) {

                sb.append('0');

            }

            sb.append(Integer.toHexString(v));//.append("-");

        }

        return sb.toString();
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                            + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    public static byte[] encrypter(final String message, SecretKey cle)
                    throws NoSuchAlgorithmException, NoSuchPaddingException,
                    InvalidKeyException, IllegalBlockSizeException, BadPaddingException, java.security.InvalidKeyException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, cle);
        byte[] donnees = message.getBytes();

        return cipher.doFinal(donnees);
    }

    public static String decrypter(final byte[] donnees, SecretKey cle)
                    throws NoSuchAlgorithmException, NoSuchPaddingException,
                    InvalidKeyException, IllegalBlockSizeException, BadPaddingException, java.security.InvalidKeyException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, cle);

        return new String(cipher.doFinal(donnees));
    }

    public static void main(String[] args) throws java.security.InvalidKeyException {

        final String message = "Java is the best";

        KeyGenerator keyGen;
        try {
            keyGen = KeyGenerator.getInstance("AES");
            SecretKey cle = keyGen.generateKey();

            String hexKey = brutToHexa(cle.getEncoded());

            byte[] enc = encrypter(message, cle);
            System.out.print("encrypted text : ");
            System.out.println(DatatypeConverter.printBase64Binary(enc));

            String dec = decrypter(enc, cle);
            System.out.println("decrypted text : " + dec);

            decryptWith(hexKey, brutToHexa(enc));

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
                        IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
    }

    public static void decryptWith(String hexKey, String hexMessage) throws java.security.InvalidKeyException {
        try {

            byte[] byteKey = hexStringToByteArray(hexKey);
            SecretKey secretKey = new SecretKeySpec(byteKey, "AES");

            byte[] message = hexStringToByteArray(hexMessage);

            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            String dec = new String(cipher.doFinal(message));
            System.out.println("texte decrypte : " + dec);

        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
    }
}

现在打印...

encrypted text : jq1S6WI0XsW6jmPQmCoZheVKEUZj5zOJZoR13jNdbYE=
decrypted text : Java is the best
texte decrypte : Java is the best

【讨论】:

  • 问题在于将字符串转换为十六进制,我使用了这种方法,它可以工作。
【解决方案2】:

问题在于将字符串转换为十六进制,我使用了这种方法并且它有效:

public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多