国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

java:AES加密和解密

這篇具有很好參考價值的文章主要介紹了java:AES加密和解密。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

java:AES加密和解密

1 前言

對稱加密,即單秘鑰加密,指加密和解密的過程中,使用相同的秘鑰,相比于非對稱加密,因僅有一把鑰匙,故而速度更快,更適合解密大文件(常見于如視頻文件的加密解密中)。AES算法就屬于對稱加密中的一種。

2 使用

依賴引入:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.6</version>
</dependency>

<!--  spring-boot 3.12.0  -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

AES加密與解密的工具類封裝:

package com.xiaoxu.crawler.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.StringUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author xiaoxu
 * @date 2022-11-06 21:24
 * crawlerJ:com.xiaoxu.crawler.utils.AESUtils
 */
public class AESUtils {

    private static final String AES_ALGORITHM = "AES";

    private static final String UTF8 = StandardCharsets.UTF_8.name();

    /* AES加密 String */
    public static String encryptStrAES(String text, String key){
        if(!StringUtils.hasLength(text)){
            ExcpUtils.throwExp("encode text should not be null or empty.");
        }
        byte[] encodeBytes = encryptByteAES(text.getBytes(StandardCharsets.UTF_8), key);
        return Base64.encodeBase64String(encodeBytes);
    }

    /* AES解密 String*/
    public static String decryptStrAES(String text, String key){
        if(!StringUtils.hasLength(text)){
            ExcpUtils.throwExp("decode text should not be null or empty.");
        }
        byte[] decodeBytes = decryptByteAES(Base64.decodeBase64(text.getBytes(StandardCharsets.UTF_8)), key);
        return new String(decodeBytes, StandardCharsets.UTF_8);
    }

    /* AES加密 originalBytes */
    public static byte[] encryptByteAES(byte[] originalBytes, String key){
        if(ArrayUtils.isEmpty(originalBytes)){
            ExcpUtils.throwExp("encode originalBytes should not be empty.");
        }
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("key :" + key + ", encode key should not be null or empty.");
        }
        Cipher cipher = getAESCipher(key, Cipher.ENCRYPT_MODE);
        byte[] encodeBytes = null;
        try {
            encodeBytes = cipher.doFinal(originalBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            ExcpUtils.throwExp(e.getClass().getName()+": encode byte fail. "+e.getMessage());
        }
        return encodeBytes;
    }

    /* AES解密 encryptedBytes */
    public static byte[] decryptByteAES(byte[] encryptedBytes, String key){
        if(ArrayUtils.isEmpty(encryptedBytes)){
            ExcpUtils.throwExp("decode encryptedBytes should not be empty.");
        }
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("key :" + key + ", decode key should not be null or empty.");
        }
        Cipher cipher = getAESCipher(key, Cipher.DECRYPT_MODE);
        byte[] decodeBytes = null;
        try {
            decodeBytes = cipher.doFinal(encryptedBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            ExcpUtils.throwExp(e.getClass().getName()+": decode byte fail. "+e.getMessage());
        }
        return decodeBytes;
    }

    public static Cipher getAESCipher(String key, int mode){
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("key :" + key + ", should not be null or empty.");
        }
        Cipher cipher = null;
        SecretKey secretKey;
        try {
            cipher = Cipher.getInstance(AES_ALGORITHM);
            byte[] keyBytes = key.getBytes(UTF8);
            secretKey = new SecretKeySpec(keyBytes, AES_ALGORITHM);
            cipher.init(mode, secretKey);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            ExcpUtils.throwExp(e.getClass().getName()+": get cipher instance wrong. "+e.getMessage());
        } catch (UnsupportedEncodingException u){
            ExcpUtils.throwExp(u.getClass().getName()+": key transfer bytes fail. "+u.getMessage());
        } catch (InvalidKeyException i) {
            ExcpUtils.throwExp(i.getClass().getName()+": key is invalid. "+i.getMessage());
        }
        return cipher;
    }

    public static void main(String[] args) {
        String msg = "小徐123testAes!!!";
        String key = "0382f2bcbacfa8be";
//        String key = "0382f2bcbacfa8b";
        System.out.println("AES秘鑰長度只能為16、24、32:"+key.getBytes(StandardCharsets.UTF_8).length);
        String s = encryptStrAES(msg, key);
        System.out.println("加密后:"+s);
        String s1 = decryptStrAES(s, key);
        System.out.println("解密后:"+s1);
    }


}

執(zhí)行如下:

AES秘鑰長度只能為16、2432:16
加密后:ZfZYz9Pk4RcA3QQcv+rKnjM54AQV4s/LjsRiGbkpzw8=
解密后:小徐123testAes!!!

AES的秘鑰字節(jié)數(shù)組長度僅能為16、24、32,修改秘鑰長度為15再次執(zhí)行:

public static void main(String[] args) {
    String msg = "小徐123testAes!!!";
//        String key = "0382f2bcbacfa8be";
    String key = "0382f2bcbacfa8b";
    System.out.println("AES秘鑰長度只能為16、24、32:"+key.getBytes(StandardCharsets.UTF_8).length);
    String s = encryptStrAES(msg, key);
    System.out.println("加密后:"+s);
    String s1 = decryptStrAES(s, key);
    System.out.println("解密后:"+s1);
}

結(jié)果如下,出現(xiàn)了Invalid AES key length異常:

AES秘鑰長度只能為16、2432:15
Exception in thread "main" com.xiaoxu.crawler.excp.CrawlerForJException: java.security.InvalidKeyException: key is invalid. Invalid AES key length: 15 bytes
	at com.xiaoxu.crawler.utils.ExcpUtils.throwExp(ExcpUtils.java:28)
	at com.xiaoxu.crawler.utils.AESUtils.getAESCipher(AESUtils.java:94)
	at com.xiaoxu.crawler.utils.AESUtils.encryptByteAES(AESUtils.java:50)
	at com.xiaoxu.crawler.utils.AESUtils.encryptStrAES(AESUtils.java:29)
	at com.xiaoxu.crawler.utils.AESUtils.main(AESUtils.java:104)

debug源碼可見:

AES使用的秘鑰key參數(shù)有長度限制,如下可見ElectronicCodeBook的部分源碼:

java:AES加密和解密

var2為傳入的加密的算法,為AES;var3就是秘鑰key轉(zhuǎn)換的字節(jié)數(shù)組,總共長度為15;調(diào)用的是AESCrypt的init方法,如下可見AESCrypt的init源碼:

void init(boolean var1, String var2, byte[] var3) throws InvalidKeyException {
    if (!var2.equalsIgnoreCase("AES") && !var2.equalsIgnoreCase("Rijndael")) {
        throw new InvalidKeyException("Wrong algorithm: AES or Rijndael required");
    } else if (!isKeySizeValid(var3.length)) {
        throw new InvalidKeyException("Invalid AES key length: " + var3.length + " bytes");
    } else {
        if (!MessageDigest.isEqual(var3, this.lastKey)) {
            this.makeSessionKey(var3);
            this.lastKey = (byte[])var3.clone();
        }

        this.K = this.sessionK[var1 ? 1 : 0];
    }
}

可見,isKeySizeValid(var3.length)返回false時,即拋出Invalid AES key length異常,如下為isKeySizeValid源碼:

AESCrypt部分源碼如下:

static final boolean isKeySizeValid(int var0) {
    for(int var1 = 0; var1 < AES_KEYSIZES.length; ++var1) {
        if (var0 == AES_KEYSIZES[var1]) {
            return true;
        }
    }

    return false;
}

其中AES_KEYSIZES為接口中的常量:

interface AESConstants {
    int AES_BLOCK_SIZE = 16;
    int[] AES_KEYSIZES = new int[]{16, 24, 32};
}

即AES的秘鑰字節(jié)數(shù)組長度如果不為16、24、32,將拋出Invalid AES key length異常。

由此可見,AES的秘鑰字節(jié)數(shù)組長度需限制在16、24、32內(nèi)。

package com.xiaoxu.crawler.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.StringUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xiaoxu
 * @date 2022-11-06 21:24
 * crawlerJ:com.xiaoxu.crawler.utils.AESUtils
 */
public class AESUtils {

    private static final String AES_ALGORITHM = "AES";

    private static final String UTF8 = StandardCharsets.UTF_8.name();

    private static final List<Integer> AES_KEYSIZES = Arrays.asList(16, 24, 32);

    public static String newKey(String key){
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("new key should not be empty");
        }
        boolean fl = false;
        int len = key.getBytes(StandardCharsets.UTF_8).length;
        for (int keySize : AES_KEYSIZES) {
            if(len == keySize){
                fl = true;
                break;
            }
        }
        String newKey = key;
        if(!fl){
            /* 32、24、16倒序排序 */
            List<Integer> new_sizes = AES_KEYSIZES.stream().sorted(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2-o1;
                }
            }).collect(Collectors.toList());
            int length = 0;
            for (int var0 = 0; var0 < new_sizes.size(); var0++) {
                if(len > 0 && len < new_sizes.get(new_sizes.size()-1) && var0 == new_sizes.size()-1){
                    length = len;
                }else if(new_sizes.get(var0) <= len){
                    length = new_sizes.get(var0);
                }
                if(new_sizes.get(var0) <= len || (len > 0 && len < new_sizes.get(new_sizes.size()-1)&& var0 == new_sizes.size()-1 ) ){
                    byte[] nKey = new byte[new_sizes.get(var0)];
                    for (int f = 0; f < new_sizes.get(var0); f++) {
	                    /* 不足16位的末尾補0 */
                        nKey[f] = (byte)48;
                    }
                    System.arraycopy(key.getBytes(StandardCharsets.UTF_8),0,nKey,0,length);
                    newKey = new String(nKey, StandardCharsets.UTF_8);
                    break;
                }
            }
        }
        return newKey;
    }

    /* AES加密 String */
    public static String encryptStrAES(String text, String key){
        if(!StringUtils.hasLength(text)){
            ExcpUtils.throwExp("encode text should not be null or empty.");
        }
        byte[] encodeBytes = encryptByteAES(text.getBytes(StandardCharsets.UTF_8), key);
        return Base64.encodeBase64String(encodeBytes);
    }

    /* AES解密 String*/
    public static String decryptStrAES(String text, String key){
        if(!StringUtils.hasLength(text)){
            ExcpUtils.throwExp("decode text should not be null or empty.");
        }
        byte[] decodeBytes = decryptByteAES(Base64.decodeBase64(text.getBytes(StandardCharsets.UTF_8)), key);
        return new String(decodeBytes, StandardCharsets.UTF_8);
    }

    /* AES加密 originalBytes */
    public static byte[] encryptByteAES(byte[] originalBytes, String key){
        if(ArrayUtils.isEmpty(originalBytes)){
            ExcpUtils.throwExp("encode originalBytes should not be empty.");
        }
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("key :" + key + ", encode key should not be null or empty.");
        }

        Cipher cipher = getAESCipher(key, Cipher.ENCRYPT_MODE);
        byte[] encodeBytes = null;
        try {
            encodeBytes = cipher.doFinal(originalBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            ExcpUtils.throwExp(e.getClass().getName()+": encode byte fail. "+e.getMessage());
        }
        return encodeBytes;
    }

    /* AES解密 encryptedBytes */
    public static byte[] decryptByteAES(byte[] encryptedBytes, String key){
        if(ArrayUtils.isEmpty(encryptedBytes)){
            ExcpUtils.throwExp("decode encryptedBytes should not be empty.");
        }
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("key :" + key + ", decode key should not be null or empty.");
        }
        Cipher cipher = getAESCipher(key, Cipher.DECRYPT_MODE);
        byte[] decodeBytes = null;
        try {
            decodeBytes = cipher.doFinal(encryptedBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            ExcpUtils.throwExp(e.getClass().getName()+": decode byte fail. "+e.getMessage());
        }
        return decodeBytes;
    }

    public static Cipher getAESCipher(String key, int mode){
        if(!StringUtils.hasLength(key)){
            ExcpUtils.throwExp("key :" + key + ", should not be null or empty.");
        }
        Cipher cipher = null;
        SecretKey secretKey;
        try {
            cipher = Cipher.getInstance(AES_ALGORITHM);
            byte[] keyBytes = key.getBytes(UTF8);
            secretKey = new SecretKeySpec(keyBytes, AES_ALGORITHM);
            cipher.init(mode, secretKey);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            ExcpUtils.throwExp(e.getClass().getName()+": get cipher instance wrong. "+e.getMessage());
        } catch (UnsupportedEncodingException u){
            ExcpUtils.throwExp(u.getClass().getName()+": key transfer bytes fail. "+u.getMessage());
        } catch (InvalidKeyException i) {
            ExcpUtils.throwExp(i.getClass().getName()+": key is invalid. "+i.getMessage());
        }
        return cipher;
    }

    public static void main(String[] args) {
        String msg = "小徐123testAes!!!";
//        String key = "0382f2bcbacfa8be";
        String key = "0382f2bcbacfa8b";
        System.out.println("轉(zhuǎn)換前的秘鑰長度:" + key.getBytes(StandardCharsets.UTF_8).length);
        System.out.println("轉(zhuǎn)換后秘鑰:"+newKey(key)+";長度:"+newKey(key).getBytes(StandardCharsets.UTF_8).length);

        System.out.println("AES秘鑰長度只能為16、24、32:"+newKey(key).getBytes(StandardCharsets.UTF_8).length);
        String s = encryptStrAES(msg, newKey(key));
        System.out.println("加密后:"+s);
        String s1 = decryptStrAES(s, newKey(key));
        System.out.println("解密后:"+s1);
    }
}

可如上簡單對秘鑰長度作出填充,執(zhí)行結(jié)果如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-500731.html

轉(zhuǎn)換前的秘鑰長度:15
轉(zhuǎn)換后秘鑰:0382f2bcbacfa8b0;長度:16
AES秘鑰長度只能為1624、32:16
加密后:AAz4gPXlduN+l1OX0BV9nWXqJqhXRS3ThRQXJsU0lWM=
解密后:小徐123testAes!!!

到了這里,關(guān)于java:AES加密和解密的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 國密SM4對稱加密Java加解密

    提示:國密SM4對稱加密Java加解密 國家密碼管理局 參考博文 SM4.0(原名SMS4.0)是中華人民共和國政府采用的一種分組密碼標(biāo)準(zhǔn),由國家密碼管理局于2012年3月21日發(fā)布。相關(guān)標(biāo)準(zhǔn)為“GM/T 0002-2012《SM4分組密碼算法》(原SMS4分組密碼算法)”。 SM4 代碼如下(示例): 在密碼學(xué)中

    2024年02月11日
    瀏覽(85)
  • Java:SpringBoot使用AES對JSON數(shù)據(jù)加密和解密

    客戶端和服務(wù)端都可以加密和解密,使用base64進行網(wǎng)絡(luò)傳輸 加密方 解密方 2.1、項目結(jié)構(gòu) 2.2、常規(guī)業(yè)務(wù)代碼 pom.xml Application.java WebMvcConfig.java CrossConfig.java JsonRequest.java JsonResult.java JsonResultVO.java IndexController.java UserController.java 2.3、加密的實現(xiàn) application.yml SecretData.java DecryptRequ

    2024年02月11日
    瀏覽(22)
  • 解決cryptoJS.AES默認參數(shù)加密,java無法解密的問題

    有時候我們需要跨編程語言進行加密加密。比如nodejs里面加密,java里面解密,或者反過來java加密,nodejs解密。node可以使用cryptojs,java可以使用javax.crypto.Cipher包。 網(wǎng)上有很多關(guān)于這方面的文章。然而如果node使用了默認的參數(shù)進行加密(比如現(xiàn)有業(yè)務(wù)已經(jīng)生成了一些已經(jīng)加密

    2024年02月11日
    瀏覽(75)
  • Java RSA加解密-非對稱加密-公鑰私鑰加解密(使用hutool工具)

    Java RSA加解密-非對稱加密-公鑰私鑰加解密(使用hutool工具)

    之前一篇帖子(https://blog.csdn.net/u014137486/article/details/136413532)展示了使用原生Java進行RSA加解密,本文介紹下使用當(dāng)下流行的Hutool工具進行RSA加解密的用法。 目錄 一、在Linux環(huán)境下生成公鑰、私鑰文件 二、將生成的公私鑰文件導(dǎo)入項目中并移除pem文件的前后公私鑰標(biāo)記 三、po

    2024年04月23日
    瀏覽(377)
  • AES(對稱加密)和RSA(非對稱加密)使用詳情

    ? ? ??待加密的明文以16字節(jié)分組進行加密,如果數(shù)據(jù)字節(jié)長度不是16的倍數(shù),最后的一組則需要在有效數(shù)據(jù)后面進行填充,使得數(shù)據(jù)長度變?yōu)?6字節(jié),AES填充方式分為NoPadding、PKCS5(PKCS7)、ISO10126、Zeros。 NoPadding :不填充,那就只能加密長度為16倍數(shù)的數(shù)據(jù),一般不使用; Zero

    2024年02月08日
    瀏覽(16)
  • 20.3 OpenSSL 對稱AES加解密算法

    20.3 OpenSSL 對稱AES加解密算法

    AES算法是一種對稱加密算法,全稱為高級加密標(biāo)準(zhǔn)(Advanced Encryption Standard)。它是一種分組密碼,以 128 比特為一個分組進行加密,其密鑰長度可以是 128 比特、 192 比特或 256 比特,因此可以提供不同等級的安全性。該算法采用了替代、置換和混淆等技術(shù),以及多輪加密和密

    2024年02月08日
    瀏覽(23)
  • AES 對稱加密算法

    AES 對稱加密算法

    高級加密標(biāo)準(zhǔn)(英語:Advanced Encryption Standard,縮寫:AES),是一種區(qū)塊加密標(biāo)準(zhǔn)。這個標(biāo)準(zhǔn)用來替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用。 那么為什么原來的DES會被取代呢,,原因就在于其使用56位密鑰,比較容易被破解。而AES可以使用128、192、和256位密鑰,并且

    2023年04月17日
    瀏覽(22)
  • C# 實現(xiàn)對稱加密算法(AES)與非對稱加密算法(RSA),包含前端加密對應(yīng)算法實現(xiàn)

    C# 實現(xiàn)對稱加密算法(AES)與非對稱加密算法(RSA),包含前端加密對應(yīng)算法實現(xiàn)

    一種既簡單速度又快的加密方式,加密與解密使用的都是同一個密鑰,別名又叫做:單密鑰加密;對稱加密有很多公開算法,并且因為它效率很高,所以適用于加密大量數(shù)據(jù)的場合;但其密鑰的傳輸過程是不安全的,并且容易被破解,密鑰管理起來也相對麻煩。 需要兩個密鑰

    2024年02月09日
    瀏覽(36)
  • 用java語言寫一個AES算法,使用AES(CBC模式)對數(shù)據(jù)進行加密或解密。加解密用到的密鑰(Key)和密鑰偏移量(IV),代碼實例類編寫。

    以下是一個使用Java編寫的AES算法實例,使用AES(CBC模式)對數(shù)據(jù)進行加密和解密。代碼中包括了生成隨機密鑰和密鑰偏移量的方法。 java Copy code import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidAlgorithmParameterException; import

    2024年02月07日
    瀏覽(33)
  • 前端使用AES密碼加密、解密,使用詳細(crypto加密解密,前后端分離,AES加密解密)

    1、 首先安裝?crypto-js插件,安裝命令如下:? ? -S等同于--save,保存在package.json文件中,是在dependencies 下, --save安裝包信息將加入到dependencies(生產(chǎn)環(huán)境)中,生產(chǎn)階段的依賴,也就是項目運行時的依賴,就是程序上線后仍然需要依賴; -D等同于--save-dev,也保存在package.j

    2024年02月11日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包