Java реализует класс инструментов шифрования и дешифрования AES ECP PKCS5Padding.

Java

Java реализуетAES/ECB/PKCS5PaddingИнструменты алгоритма шифрования и дешифрования

  • Алгоритм шифрования: AES
  • Режим: ЕЦБ
  • Код дополнения: PKCS5Padding

1. Инструменты

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;

/**
 * Created by @author yihui in 19:12 20/1/2.
 */
@Slf4j
public class EncryptUtil {
    private static final String KEY_ALGORITHM = "AES";
    /**
     * 算法/模式/补码方式
     */
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final String CODE = "utf-8";

    @Setter
    @Getter
    public static String encryptKey;

    public static String encrypt(String content) {
        return encrypt(content, encryptKey);
    }

    /**
     * 加密
     *
     * @param content
     * @param key
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, String key) {
        try {
            byte[] encrypted = encrypt2bytes(content, key);
            return Base64Utils.encodeToString(encrypted);
        } catch (Exception e) {
            log.error("failed to encrypt: {} of {}", content, e);
            return null;
        }
    }

    public static byte[] encrypt2bytes(String content, String key) {
        try {
            byte[] raw = key.getBytes(CODE);
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            return cipher.doFinal(content.getBytes(CODE));
        } catch (Exception e) {
            log.error("failed to encrypt: {} of {}", content, e);
            return null;
        }
    }

    public static String decrypt(String content) {
        try {
            return decrypt(content, encryptKey);
        } catch (Exception e) {
            log.error("failed to decrypt: {}, e: {}", content, e);
            return null;
        }
    }

    /**
     * 解密
     *
     * @param content
     * @param key
     * @return
     * @throws Exception
     */
    public static String decrypt(String content, String key) throws Exception {
        return decrypt(Base64Utils.decodeFromString(content), key);
    }

    public static String decrypt(byte[] content, String key) throws Exception {
        if (key == null) {
            log.error("AES key should not be null");
            return null;
        }

        byte[] raw = key.getBytes(CODE);
        SecretKeySpec keySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        try {
            byte[] original = cipher.doFinal(content);
            return new String(original, CqODE);
        } catch (Exception e) {
            log.error("failed to decrypt content: {}/ key: {}, e: {}", content, key, e);
            return null;
        }
    }
}

Обратите внимание, что приведенная выше реализация предоставляет два способа

  • Один из них — использовать кодировку base64 для вывода после шифрования AES, что соответствует расшифровке данных, закодированных в base64.
  • Один из них — возврат массива байтов сразу после шифрования AES, а также прямое декодирование массива байтов.

2. Тестовый случай

Мы предоставляем два зашифрованных файла для расшифровки;

шифрование и дешифрование base64

@Test
public void testEncrypt() throws Exception {
    String abc = "Hello, 一灰灰Blog!";
    String key = "JC66fRd3wj85k8Hr";
    String out = EncryptUtil.encrypt(abc, key);
    System.out.println(out);

    System.out.println(EncryptUtil.decrypt(out, key));
}

Результат на выходе выглядит следующим образом:

TKrN7VKrqsAQ4JqygeHOlG21Sd3IRJ3Y11k4kOdOG4s=
Hello, 一灰灰Blog!

Шифрование и дешифрование массива байтов

@Test
public void testEncryptByte() throws Exception {
    String abc = "Hello, 一灰灰Blog!";
    String key = "JC66fRd3wj85k8Hr";
    byte[] out = EncryptUtil.encrypt2bytes(abc, key);
    System.out.println(new String(out));

    System.out.println(EncryptUtil.decrypt(out, key));
}

Результат на выходе выглядит следующим образом:

// 加密的字节数组,就是乱码... 你没看错
L���R��������Δm�I��D���Y8��N�
Hello, 一灰灰Blog!

Почему два вышеуказанных отличия?

Если мы поместим зашифрованный массив байтов, непосредственноnew String()Получите строку, затем расшифруйте строку, вы обнаружите, что расшифровка не удалась

Просто измените приведенный выше тестовый пример

@Test
public void testEncryptByte() throws Exception {
    String abc = "Hello, 一灰灰Blog!";
    String key = "JC66fRd3wj85k8Hr";
    byte[] out = EncryptUtil.encrypt2bytes(abc, key);
    String enc = new String(out, "utf-8");
    System.out.println(enc);

    System.out.println(EncryptUtil.decrypt(enc.getBytes("utf-8"), key));
}

После выполнения было обнаружено, что расшифровка не удалась

Почему это происходит?

  • enc = new String(out, "utf-8")а такжеenc.getBytes("utf-8")Массив байтов в строку; Два процесса преобразования строки в массив байтов приведут к окончательному сгенерированному массиву байтов, который несовместим с оригиналом!!!

Дело о расшифровке удаленных ресурсов

Наконец, приведите пример расшифровки удаленно зашифрованного двоичного файла.

private void binKey(String uri, String key) throws Exception {
    // 这个文件是没有base64编码,直接上传的二进制
    URL url = new URL(uri);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    InputStream stream = connection.getInputStream();
    int lenth = connection.getContentLength();
    byte[] out = new byte[lenth];
    stream.read(out);
    stream.close();
    String ans = decrypt(out, key);
    System.out.println(ans);
}

public void testDe() throws Exception {
    String key = "5JRHMJn8xHnMDRXa";
    binKey("http://q8rnsprw0.bkt.clouddn.com/mwzz/b0001", key);
}

II. Другое

1. Серый блог:liuyueyi.github.io/hexblog

Серый личный блог, записывайте все сообщения в блогах во время учебы и работы, приглашайте всех ходить по магазинам.

2. Заявление

Это не так хорошо, как письмо. Вышеупомянутое содержание чисто из семьи. Из-за ограниченных личных способностей неизбежно будут упущения и ошибки. Если вы обнаружите ошибки или у вас есть лучшие предложения, вы можете критиковать и поправьте их.

3. Сканируйте внимание

серый блог

QrCode