java - 使用加密 key 解密文本

标签 java aes padding

我写了一个类来用 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 格式显示 key 和使用 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:给定的最终 block 未正确填充

最佳答案

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

您需要手动将十六进制 String 值转换为 byte 数组。想一想,您将一个 byte 数组转换为 String 格式,您需要再次将其转换回来。

这基本上是您的代码,但我将您的 DecryptCipherAES 放入了 decryptWith 方法中。

该示例将 key 和消息都转换为十六进制 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

关于java - 使用加密 key 解密文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25587090/

相关文章:

java - 在 AppEngine 中从 Servlet 调用 Web 服务

mysql 结果带有一些加密数据

css - wordpress 菜单描述 css 错误-无法对齐

Java:将图像保存为JPEG 倾斜问题

java - 当文本部分为空白并且按下按钮时(在 android studio 中),如何显示 toast 消息?

java - 编写一个 junit 测试来测试集合的大小

java - Android NDK 使用 gradle 和 jitpack 引入 JNI 东西?

android - Android 中的 AES key 生成

Java KeyStore setEntry() 使用 AES SecretKey

html - CSS - IE 中的填充问题?