¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | package org.springblade.core.tool.utils; |
| | | |
| | | import org.springframework.lang.Nullable; |
| | | import org.springframework.util.Assert; |
| | | |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.spec.IvParameterSpec; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import java.nio.charset.Charset; |
| | | import java.util.Arrays; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * å®å
¨å
¼å®¹å¾®ä¿¡æä½¿ç¨çAESå å¯å·¥å
·ç±» |
| | | * aesçkeyå¿
é¡»æ¯256byteé¿ï¼æ¯å¦32个å符ï¼ï¼å¯ä»¥ä½¿ç¨AesKit.genAesKey()æ¥çæä¸ç»key |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class AesUtil { |
| | | |
| | | public static final Charset DEFAULT_CHARSET = Charsets.UTF_8; |
| | | |
| | | /** |
| | | * è·åå¯é¥ |
| | | * |
| | | * @return {String} |
| | | */ |
| | | public static String genAesKey() { |
| | | return StringUtil.random(32); |
| | | } |
| | | |
| | | /** |
| | | * å å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] encrypt(String content, String aesTextKey) { |
| | | return encrypt(content.getBytes(DEFAULT_CHARSET), aesTextKey); |
| | | } |
| | | |
| | | /** |
| | | * å å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param charset ç¼ç |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] encrypt(String content, Charset charset, String aesTextKey) { |
| | | return encrypt(content.getBytes(charset), aesTextKey); |
| | | } |
| | | |
| | | /** |
| | | * å å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] encrypt(byte[] content, String aesTextKey) { |
| | | return encrypt(content, Objects.requireNonNull(aesTextKey).getBytes(DEFAULT_CHARSET)); |
| | | } |
| | | |
| | | /** |
| | | * hexå å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | public static String encryptToHex(String content, String aesTextKey) { |
| | | return HexUtil.encodeToString(encrypt(content, aesTextKey)); |
| | | } |
| | | |
| | | /** |
| | | * hexå å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | public static String encryptToHex(byte[] content, String aesTextKey) { |
| | | return HexUtil.encodeToString(encrypt(content, aesTextKey)); |
| | | } |
| | | |
| | | /** |
| | | * Base64å å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | public static String encryptToBase64(String content, String aesTextKey) { |
| | | return Base64Util.encodeToString(encrypt(content, aesTextKey)); |
| | | } |
| | | |
| | | /** |
| | | * Base64å å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | public static String encryptToBase64(byte[] content, String aesTextKey) { |
| | | return Base64Util.encodeToString(encrypt(content, aesTextKey)); |
| | | } |
| | | |
| | | /** |
| | | * hexè§£å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | @Nullable |
| | | public static String decryptFormHexToString(@Nullable String content, String aesTextKey) { |
| | | byte[] hexBytes = decryptFormHex(content, aesTextKey); |
| | | if (hexBytes == null) { |
| | | return null; |
| | | } |
| | | return new String(hexBytes, DEFAULT_CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * hexè§£å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | @Nullable |
| | | public static byte[] decryptFormHex(@Nullable String content, String aesTextKey) { |
| | | if (StringUtil.isBlank(content)) { |
| | | return null; |
| | | } |
| | | return decryptFormHex(content.getBytes(DEFAULT_CHARSET), aesTextKey); |
| | | } |
| | | |
| | | /** |
| | | * hexè§£å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] decryptFormHex(byte[] content, String aesTextKey) { |
| | | return decrypt(HexUtil.decode(content), aesTextKey); |
| | | } |
| | | |
| | | /** |
| | | * Base64è§£å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | @Nullable |
| | | public static String decryptFormBase64ToString(@Nullable String content, String aesTextKey) { |
| | | byte[] hexBytes = decryptFormBase64(content, aesTextKey); |
| | | if (hexBytes == null) { |
| | | return null; |
| | | } |
| | | return new String(hexBytes, DEFAULT_CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * Base64è§£å¯ |
| | | * |
| | | * @param content ææ¬å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | @Nullable |
| | | public static byte[] decryptFormBase64(@Nullable String content, String aesTextKey) { |
| | | if (StringUtil.isBlank(content)) { |
| | | return null; |
| | | } |
| | | return decryptFormBase64(content.getBytes(DEFAULT_CHARSET), aesTextKey); |
| | | } |
| | | |
| | | /** |
| | | * Base64è§£å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] decryptFormBase64(byte[] content, String aesTextKey) { |
| | | return decrypt(Base64Util.decode(content), aesTextKey); |
| | | } |
| | | |
| | | /** |
| | | * è§£å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return {String} |
| | | */ |
| | | public static String decryptToString(byte[] content, String aesTextKey) { |
| | | return new String(decrypt(content, aesTextKey), DEFAULT_CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * è§£å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesTextKey ææ¬å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] decrypt(byte[] content, String aesTextKey) { |
| | | return decrypt(content, Objects.requireNonNull(aesTextKey).getBytes(DEFAULT_CHARSET)); |
| | | } |
| | | |
| | | /** |
| | | * è§£å¯ |
| | | * |
| | | * @param content å
容 |
| | | * @param aesKey å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] encrypt(byte[] content, byte[] aesKey) { |
| | | return aes(Pkcs7Encoder.encode(content), aesKey, Cipher.ENCRYPT_MODE); |
| | | } |
| | | |
| | | /** |
| | | * å å¯ |
| | | * |
| | | * @param encrypted å
容 |
| | | * @param aesKey å¯é¥ |
| | | * @return byte[] |
| | | */ |
| | | public static byte[] decrypt(byte[] encrypted, byte[] aesKey) { |
| | | return Pkcs7Encoder.decode(aes(encrypted, aesKey, Cipher.DECRYPT_MODE)); |
| | | } |
| | | |
| | | /** |
| | | * aseå å¯ |
| | | * |
| | | * @param encrypted å
容 |
| | | * @param aesKey å¯é¥ |
| | | * @param mode æ¨¡å¼ |
| | | * @return byte[] |
| | | */ |
| | | private static byte[] aes(byte[] encrypted, byte[] aesKey, int mode) { |
| | | Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32"); |
| | | try { |
| | | Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); |
| | | SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); |
| | | IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16)); |
| | | cipher.init(mode, keySpec, iv); |
| | | return cipher.doFinal(encrypted); |
| | | } catch (Exception e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æä¾åºäºPKCS7ç®æ³çå è§£å¯æ¥å£. |
| | | */ |
| | | private static class Pkcs7Encoder { |
| | | private static final int BLOCK_SIZE = 32; |
| | | |
| | | private static byte[] encode(byte[] src) { |
| | | int count = src.length; |
| | | // 计ç®éè¦å¡«å
ç使° |
| | | int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); |
| | | // è·å¾è¡¥ä½æç¨çå符 |
| | | byte pad = (byte) (amountToPad & 0xFF); |
| | | byte[] pads = new byte[amountToPad]; |
| | | for (int index = 0; index < amountToPad; index++) { |
| | | pads[index] = pad; |
| | | } |
| | | int length = count + amountToPad; |
| | | byte[] dest = new byte[length]; |
| | | System.arraycopy(src, 0, dest, 0, count); |
| | | System.arraycopy(pads, 0, dest, count, amountToPad); |
| | | return dest; |
| | | } |
| | | |
| | | private static byte[] decode(byte[] decrypted) { |
| | | int pad = decrypted[decrypted.length - 1]; |
| | | if (pad < 1 || pad > BLOCK_SIZE) { |
| | | pad = 0; |
| | | } |
| | | if (pad > 0) { |
| | | return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); |
| | | } |
| | | return decrypted; |
| | | } |
| | | } |
| | | } |