使用AES/CBC/PKCS7Padding方式加解密


一、主要工具类

/**
 * AES加解密工具类
 *
 * @Date 2020/12/5-14:11
 */
public class EncryptAndDecryptUtil {
    /**
     * 密钥算法 AES
     */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * 加解密算法/工作模式/填充方式
     * java支持PKCS5Padding、不支持PKCS7Padding
     * Bouncy Castle支持PKCS7Padding填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";

    /**
     * 偏移量,CBC模式需要
     * 与其他语言平台使用的需一致才能通用加解密
     */
    private static final String IV = "0000000000000000";

    public static final String ENCODING = "UTF-8";

    static {
        // 是PKCS7Padding填充方式,则需要添加Bouncy Castle支持
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * AES加密方法
     *
     * @param source 原文
     * @param password 加密密钥
     * @return 密文
     */
    public static String encrypt(String source, String password) throws Exception {
        byte[] sourceBytes = source.getBytes(ENCODING);
        byte[] passwordBytes = password.getBytes(ENCODING);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes(ENCODING));
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(passwordBytes, KEY_ALGORITHM), iv);
        byte[] encryptBytes = cipher.doFinal(sourceBytes);
        String encryptText = Base64.encodeBase64String(encryptBytes);
        return encryptText;
    }

    /**
     * AES解密方法
     *
     * @param encryptText 密文
     * @param password 密码
     * @return 原文
     */
    public static String decrypt(String encryptText, String password) throws Exception {
        byte[] sourceBytes = Base64.decodeBase64(encryptText);
        byte[] passwordBytes = password.getBytes(ENCODING);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes(ENCODING));
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(passwordBytes, KEY_ALGORITHM), iv);
        byte[] decryptBytes = cipher.doFinal(sourceBytes);
        return new String(decryptBytes, ENCODING);
    }

  // AES密码长度只能为16/24/32个字符长度
public static String checkPassword(Scanner scanner, String pwd) { while (pwd == null || "".equals(pwd) || pwd.length() < 16) { System.out.print("密码长度需为16个或以上长度的字符,请重新输入:"); pwd = scanner.next().trim(); } if (pwd.length() < 32) { int lessNum = 32 - pwd.length(); StringBuilder builder = new StringBuilder(32); builder.append(pwd); for (int i = 0; i < lessNum; i++) { builder.append("a"); } pwd = builder.toString(); } if (pwd.length() > 32) { pwd = pwd.substring(0, 32); } return pwd; } }

 

二、Main方法

/**
 * @Description
 * @Date 2020/12/5-21:10
 */
public class MainClass {
    public static void main(String[] args) {
        int mark = 1;
        Scanner scanner = new Scanner(System.in);
        System.out.print("请选择模式->输入1为加密,输入2为解密: ");
        try {
            if (scanner.hasNext("[1-2]")) {
                if (scanner.nextInt() == 1) {
                    System.out.print("请输入要加密的原文(不能包含中文): ");
                    String content = scanner.next().trim();
                    while (content == null || "".equals(content) || content.length() > 256) {
                        System.out.print("原文长度须在1-256个字符之间,不能包含中文,请重新输入:");
                        content = scanner.next().trim();
                    }
                    System.out.print("请输入加密的密码: ");
                    String pwd = scanner.next().trim();
                    pwd = EncryptAndDecryptUtil.checkPassword(scanner, pwd);
                    String encryptString = EncryptAndDecryptUtil.encrypt(content, pwd);
                    System.out.println("加密内容为: " + encryptString);
                } else {
                    mark = 2;
                    System.out.print("请输入要解密的密文: ");
                    String encryptString = scanner.next().trim();
                    while (encryptString == null || "".equals(encryptString) || encryptString.length() > 1024) {
                        System.out.print("密文长度须在1-1024个字符之间,请重新输入:");
                        encryptString = scanner.next().trim();
                    }
                    System.out.print("请输入解密的密码(与之前加密的密码一致): ");
                    String pwd = scanner.next().trim();
                    pwd = EncryptAndDecryptUtil.checkPassword(scanner, pwd);
                    String decryptString = EncryptAndDecryptUtil.decrypt(encryptString, pwd);
                    System.out.println("解密内容为: " + decryptString);
                }
            } else {
                System.out.println("输入错误!");
            }
        } catch (Exception e) {
            if (mark == 1) {
                System.out.println("加密失败");
            } else {
                System.out.println("解密失败");
            }
        }
    }
}

 

三、pom.xml的Maven依赖与构建的配置

<dependencies>
    <dependency>
      <groupId>org.bouncycastle</groupId>
      <artifactId>bcprov-jdk16</artifactId>
      <version>1.46</version>
    </dependency>

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

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.6</version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
              <mainClass>me.jar.MainClass</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.10</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM