美文网首页
对称加密 AES

对称加密 AES

作者: 十二找十三 | 来源:发表于2020-03-09 13:52 被阅读0次
package com.bc.mcode.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class AesSecure {
    private static final String password = "f010e34ec4a3b525";
    private static final int iterationCount = 1024;
    private static final int keyLength = 256;
    private static final int saltLength = keyLength / 8;


    public static void main(String[] args) {
        Map<String, String> temp1 = encoder("18843141234", true);
        Map<String, String> temp2 = encoder("18843141234", false);
        System.out.println(temp1);
        System.out.println(temp2);

        System.out.println(decoder(temp1.get("cipher"), true, temp1.get("salt"), temp1.get("iv")));
        System.out.println(decoder(temp2.get("cipher"), false, temp2.get("salt"), temp2.get("iv")));


    }


    /**
     *
     * 加密
     * @param text 要加密的明文
     * @param flag 阀值 true:加密结果不一样 false:加密结果一样
     * @return
     */
    public static HashMap<String, String> encoder(String text, boolean flag) {
        Objects.requireNonNull(text);

        if (flag) {
            return encoderReally(text);
        } else {
            HashMap<String, String> temp = encoderReally(text, password);
            temp.put("salt", Base64.getEncoder().encodeToString(temp.get("salt").getBytes()));

            return temp;
        }
    }

    /**
     * 解密
     * @param text 密文
     * @param flag 阀值 true:加密结果不一样 false:加密结果一样
     * @param salt 盐  当阀值为false时可以不传
     * @param iv 偏移量 当阀值为false时可以不传
     * @return
     */
    public static String decoder(String text, boolean flag, String salt, String iv) {
        Objects.requireNonNull(text);

        if (flag) {
            Objects.requireNonNull(salt);
            Objects.requireNonNull(iv);
            return decoderReally(text, salt, iv);
        } else {
            String temp = Base64.getEncoder().encodeToString(password.getBytes());
            return decoderReally(text, temp, temp);
        }
    }



    private static SecretKey getKey(KeySpec keySpec) {

        SecretKeyFactory keyFactory = null;

        try {
            keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        byte[] keyBytes = new byte[0];

        try {
            keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        SecretKey key = new SecretKeySpec(keyBytes, "AES");
        return key;
    }




    private static HashMap<String, String> encoderReally(String text) {
        HashMap<String, String> map = new HashMap<String, String>();

        try {
            SecureRandom random = new SecureRandom();
            byte[] salt = new byte[saltLength];
            random.nextBytes(salt);

            KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, keyLength);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = new byte[cipher.getBlockSize()];

            random.nextBytes(iv);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            cipher.init(cipher.ENCRYPT_MODE, getKey(keySpec), ivParameterSpec);
            byte[] ciphertext = cipher.doFinal(text.getBytes("utf-8"));

            Encoder encoder = Base64.getEncoder();

            map.put("iv", encoder.encodeToString(iv));
            map.put("salt", encoder.encodeToString(salt));
            map.put("cipher", encoder.encodeToString(ciphertext));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return map;
    }

    private static HashMap<String, String> encoderReally(String text, String salt) {
        HashMap<String, String> map = new HashMap<String, String>();

        try {

            byte[] saltBytes = salt.getBytes();

            KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, iterationCount, keyLength);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            byte[] iv = password.getBytes();

            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            cipher.init(cipher.ENCRYPT_MODE, getKey(keySpec), ivParameterSpec);

            byte[] ciphertext = cipher.doFinal(text.getBytes("utf-8"));

            Encoder encoder = Base64.getEncoder();

            map.put("iv", encoder.encodeToString(iv));
            map.put("salt", encoder.encodeToString(saltBytes));
            map.put("cipher", encoder.encodeToString(ciphertext));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return map;
    }

    private static String decoderReally(String text, String salt, String iv) {
        String value = null;
        Decoder decoder = Base64.getDecoder();
        try {
            byte[] saltBytes = decoder.decode(salt);
            KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, iterationCount, keyLength);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] ivBytes = decoder.decode(iv);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

            cipher.init(cipher.DECRYPT_MODE, getKey(keySpec), ivParameterSpec);
            byte[] ciphertext = cipher.doFinal(decoder.decode(text));

            value = new String(ciphertext, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return value;
    }
}


相关文章

网友评论

      本文标题:对称加密 AES

      本文链接:https://www.haomeiwen.com/subject/mkhpdhtx.html