AES加解密工具类 (AES/CBC/pkcs7 NoPadding)

项目中频繁使用到AES,网上给出的工具类比较杂乱,这里整理一个常用的AES工具类,进行加解密,细节如下:

aesKey:32/16 位

iv:aesKey

mode:CBC

padding:pkcs7

pkcs7参考网上使用Java实现填充


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.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Objects;

/**
 *
 * AES工具类
 * @author lizheng
 */
public class AesUtil {

	public static final Charset DEF_CHARSET = StandardCharsets.UTF_8;

	public static final String CIPHER_INSTANCE = "AES/CBC/NoPadding";

	public static String decryptFormBase64ToString(String content, String aesTextKey) {
		byte[] bytes = decryptFormBase64(content, aesTextKey);
		if (bytes == null) {
			return null;
		}
		return new String(bytes, DEF_CHARSET);
	}

	public static byte[] decryptFormBase64(String content, String aesTextKey) {
		if (content == null || content.length() == 0 ) {
			return null;
		}
		return decryptFormBase64(content.getBytes(DEF_CHARSET), aesTextKey);
	}

	public static byte[] decryptFormBase64(byte[] content, String aesTextKey) {
		return decrypt(base64Decode(content), aesTextKey);
	}

	public static byte[] decrypt(byte[] content, String aesTextKey) {
		return decrypt(content, Objects.requireNonNull(aesTextKey).getBytes(DEF_CHARSET));
	}

	public static byte[] decrypt(byte[] encrypted, byte[] aesKey) {
		return Pkcs7Encoder.decode(aes(encrypted, aesKey, Cipher.DECRYPT_MODE));
	}

	public static String encryptToBase64(String content, String aesTextKey) {
		return base64EncodeToString(encrypt(content, aesTextKey));
	}

	public static String encryptToBase64(byte[] content, String aesTextKey) {
		return base64EncodeToString(encrypt(content, aesTextKey));
	}

	public static byte[] encrypt(String content, String aesTextKey) {
		return encrypt(content.getBytes(DEF_CHARSET), aesTextKey);
	}

	public static byte[] encrypt(byte[] content, String aesTextKey) {
		return encrypt(content, Objects.requireNonNull(aesTextKey).getBytes(DEF_CHARSET));
	}

	public static byte[] encrypt(byte[] content, byte[] aesKey) {
		return aes(Pkcs7Encoder.encode(content), aesKey, Cipher.ENCRYPT_MODE);
	}

	private static byte[] aes(byte[] encrypted, byte[] aesKey, int mode) {
		Assert.isTrue(aesKey.length == 32 || aesKey.length == 16, "AesKey's length must be 16 or 32");
		try {
			Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE);
			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 new RuntimeException(e);
		}
	}

	private static byte[] base64Decode(byte[] src) {
		return src.length == 0 ? src : Base64.getDecoder().decode(src);
	}

	private static String base64EncodeToString(byte[] src) {
		return src.length == 0 ? "" : new String(Base64.getEncoder().encode(src), DEF_CHARSET);
	}

	private static class Pkcs7Encoder {
		private static final int BLOCK_SIZE = 32;

		private static byte[] encode(byte[] src) {
			int count = src.length;
			// 计算需要填充的位数
			int toPad = BLOCK_SIZE - (count % BLOCK_SIZE);
			// 补位所用的字符
			byte pad = (byte) (toPad & 0xFF);
			byte[] pads = new byte[toPad];
			for (int index = 0; index < toPad; index++) {
				pads[index] = pad;
			}
			int length = count + toPad;
			byte[] dest = new byte[length];
			System.arraycopy(src, 0, dest, 0, count);
			System.arraycopy(pads, 0, dest, count, toPad);
			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;
		}
	}

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以为您提供一个使用Golang编写的AES/ECB/PKCS5Padding的加密解密方法工具类。下面是示例代码: ```go package main import ( "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" ) func main() { key := []byte("0123456789abcdef") plaintext := []byte("Hello, World!") ciphertext, err := encrypt(key, plaintext) if err != nil { fmt.Println("Error encrypting:", err) return } fmt.Println("Ciphertext:", base64.StdEncoding.EncodeToString(ciphertext)) decryptedText, err := decrypt(key, ciphertext) if err != nil { fmt.Println("Error decrypting:", err) return } fmt.Println("Decrypted text:", string(decryptedText)) } func encrypt(key, plaintext []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } // Add PKCS5 padding to the plaintext padding := aes.BlockSize - len(plaintext)%aes.BlockSize padText := append(plaintext, bytes.Repeat([]byte{byte(padding)}, padding)...) ciphertext := make([]byte, len(padText)) // ECB mode does not require an IV mode := cipher.NewCBCEncrypter(block, key[:aes.BlockSize]) mode.CryptBlocks(ciphertext, padText) return ciphertext, nil } func decrypt(key, ciphertext []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } // ECB mode does not require an IV mode := cipher.NewCBCDecrypter(block, key[:aes.BlockSize]) mode.CryptBlocks(ciphertext, ciphertext) // Remove PKCS5 padding padding := ciphertext[len(ciphertext)-1] return ciphertext[:len(ciphertext)-int(padding)], nil } ``` 在这个示例中,我们使用了crypto/aes和crypto/cipher库来进行AES加密和解密。`encrypt`函数接受一个密钥和明文作为输入,并返回加密后的密文。`decrypt`函数接受同样的密钥和密文,返回解密后的明文。 请注意,这里使用的是ECB模式,这是一种基本的加密模式,不含有初始化向量(IV)。在实际应用中,推荐使用更安全的加密模式,如CBC模式,并生成随机的IV。 希望这个示例对您有帮助!如有任何疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值