zoukankan      html  css  js  c++  java
  • Java AES512加密算法

    AES - 高级加密标准:

      高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一

    AES 算法在工作中使用很频繁, 借着这次项目中使用做一下总结, 本次主要是正对 AES512 来讲解。

    开发前准备工作:

    由于Java 运行环境中的 policy文件是受限的,对AES512不支持。解决方案如下:

      1:policy文件位于${java_home}/jre/lib/security目录下

      2: 去除该限制需下载 Java Cryptography Extension (JCE) Unlimited Strength JurisdictionPolicy Files,
        覆盖上述目录下的对应jar文件(local_policy.jar,US_export_policy.jar)

      3: jar 官方下载路径

         JDK6 http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

        JDK7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
        JDK8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

    做完这三步 下面直接上代码:

    AES512 加密方法 

      1 import java.io.UnsupportedEncodingException;
      2 import java.security.InvalidAlgorithmParameterException;
      3 import java.security.InvalidKeyException;
      4 import java.security.NoSuchAlgorithmException;
      5 
      6 import javax.crypto.BadPaddingException;
      7 import javax.crypto.Cipher;
      8 import javax.crypto.IllegalBlockSizeException;
      9 import javax.crypto.NoSuchPaddingException;
     10 import javax.crypto.spec.IvParameterSpec;
     11 import javax.crypto.spec.SecretKeySpec;
     12 
     13 import org.message.encrypt.tool.Encode;
     14 import org.message.encrypt.tool.Numeric;
     15 
     16 import com.google.common.io.BaseEncoding;
     17 
     18 public class AESCipher {
     19     private static final String ALGORITHM_AES256 = "AES/CBC/PKCS5Padding";// "AES/CBC/PKCS7Padding";
     20     private final SecretKeySpec secretKeySpec;
     21     private static final String CHARSET = "UTF-8";
     22     private static final String DEFAULT_IV = "iv is default value";
     23     private Cipher cipher;
     24     private IvParameterSpec iv;
     25 
     26     
     27     public AESCipher(String key) {
     28         this(key, DEFAULT_IV);
     29     }
     30 
     31     public AESCipher(String key, String iv) {
     32         this(Numeric.hexStringToByteArray(key), Numeric.hexStringToByteArray(iv));
     33     }
     34 
     35     private AESCipher(byte[] key, byte[] iv) {
     36         // Security.addProvider(new BouncyCastleProvider());
     37         if (null == key || key.length != 32) {
     38             throw new RuntimeException("input params key must be 32bit bytes array");
     39         }
     40         if (null == iv || iv.length != 16) {
     41             throw new RuntimeException("input params iv must be 16bit bytes array");
     42         }
     43         this.secretKeySpec = new SecretKeySpec(key, "AES");
     44         this.iv = new IvParameterSpec(iv);
     45         try {
     46             this.cipher = Cipher.getInstance(ALGORITHM_AES256);
     47         } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
     48             throw new RuntimeException("instantiation objects Cipher exception");
     49         }
     50     }
     51 
     52     /**
     53      * AES Encrypt algorithm
     54      * 
     55      * @param encryptSource
     56      *            not null string
     57      * @return after AES encrypt result , the type of the string
     58      */
     59     public String getEncryptedMessage(final String encryptSource) {
     60         Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
     61         byte[] encryptedTextBytes = null;
     62         try {
     63             encryptedTextBytes = cipher.doFinal(encryptSource.getBytes(CHARSET));
     64         } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
     65             throw new RuntimeException("AES encrypt exception");
     66         }
     67         return Encode.baseEncode(encryptedTextBytes);
     68     }
     69 
     70     /**
     71      * AES decrypt algorithm
     72      * 
     73      * @param decryptSource
     74      *            AES encrypted cipher, type of String
     75      * @return decrypted plaintext, type of string
     76      */
     77     public String getDecryptMessage(String decryptSource) {
     78 
     79         Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
     80         byte[] encryptedTextBytes = null;
     81         String decryptResult = null;
     82         try {
     83             encryptedTextBytes = cipher.doFinal(BaseEncoding.base64().decode(decryptSource));
     84         } catch (IllegalBlockSizeException | BadPaddingException e) {
     85             throw new RuntimeException("AES decrypt exception");
     86         }
     87         try {
     88             decryptResult = new String(encryptedTextBytes, CHARSET);
     89         } catch (UnsupportedEncodingException e) {
     90             throw new RuntimeException("bytes array convert into string exception");
     91         }
     92         return decryptResult;
     93     }
     94 
     95     private Cipher getCipher(int encryptMode) {
     96         try {
     97             cipher.init(encryptMode, secretKeySpec, iv);
     98         } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
     99             throw new RuntimeException("init objects Cipher exception");
    100         }
    101         return cipher;
    102     }
    103 }
    View Code

    Encode 工具类

     1 import com.google.common.io.BaseEncoding;
     2 
     3 public class Encode {
     4 
     5     /**
     6      * byte[] convert into string ,use base encode default value BASE64
     7      * 
     8      * @param encodeMassage
     9      *            not null byte[]
    10      * @return after encode result
    11      */
    12     public static String baseEncode(final byte[] encodeMassage) {
    13         return baseEncode(encodeMassage, BaseType.BASE64);
    14     }
    15 
    16     /**
    17      * byte[] convert into string ,use base encode default value BASE64
    18      * 
    19      * @param encodeMassage
    20      *            not null byte[]
    21      * @param encoder
    22      *            of type please see enum type of inner class , the class name
    23      *            'BaseType'
    24      * @return after encode result , the type of string
    25      */
    26     public static String baseEncode(final byte[] encodeMassage, final BaseType encoder) {
    27         String baseResult = null;
    28         switch (encoder) {
    29         case BASE64:
    30             baseResult = BaseEncoding.base64().encode(encodeMassage);
    31             break;
    32         case BASE32:
    33             baseResult = BaseEncoding.base32().encode(encodeMassage);
    34             break;
    35         case BASE32HEX:
    36             baseResult = BaseEncoding.base32Hex().encode(encodeMassage);
    37             break;
    38         case BASE16:
    39             baseResult = BaseEncoding.base16().encode(encodeMassage);
    40             break;
    41         default:
    42             break;
    43         }
    44         return baseResult;
    45     }
    46 
    47     /**
    48      * string convert into byte[], use base decode
    49      * 
    50      * @param decodeMassage
    51      *            not null string
    52      * @return after decode result , the type of byte[]
    53      */
    54     public static byte[] baseDecode(final String decodeMassage) {
    55         return baseDecode(decodeMassage, BaseType.BASE64);
    56     }
    57 
    58     public static byte[] baseDecode(final String decodeMassage, final BaseType encoder) {
    59         byte[] baseResult = null;
    60         switch (encoder) {
    61         case BASE64:
    62             baseResult = BaseEncoding.base64().decode(decodeMassage);
    63             break;
    64         case BASE32:
    65             baseResult = BaseEncoding.base32().decode(decodeMassage);
    66             break;
    67         case BASE32HEX:
    68             baseResult = BaseEncoding.base32Hex().decode(decodeMassage);
    69             break;
    70         case BASE16:
    71             baseResult = BaseEncoding.base16().decode(decodeMassage);
    72             break;
    73         default:
    74             break;
    75         }
    76         return baseResult;
    77     }
    78 
    79     enum BaseType {
    80         BASE64, BASE32, BASE32HEX, BASE16;
    81     }
    82 }
    View Code

    Numeric 工具类

      1 import java.math.BigDecimal;
      2 import java.math.BigInteger;
      3 import java.util.Arrays;
      4 
      5 /**
      6  * <p>Message codec functions.</p>
      7  *
      8  * <p>Implementation as per https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding</p>
      9  */
     10 public final class Numeric {
     11 
     12     private static final String HEX_PREFIX = "0x";
     13 
     14     private Numeric() {
     15     }
     16 
     17     public static String encodeQuantity(BigInteger value) {
     18         if (value.signum() != -1) {
     19             return HEX_PREFIX + value.toString(16);
     20         } else {
     21             throw new RuntimeException("Negative values are not supported");
     22         }
     23     }
     24 
     25     public static BigInteger decodeQuantity(String value) {
     26         if (!isValidHexQuantity(value)) {
     27             throw new RuntimeException("Value must be in format 0x[1-9]+[0-9]* or 0x0");
     28         }
     29         try {
     30             return new BigInteger(value.substring(2), 16);
     31         } catch (NumberFormatException e) {
     32             throw new RuntimeException("Negative ", e);
     33         }
     34     }
     35 
     36     private static boolean isValidHexQuantity(String value) {
     37         if (value == null) {
     38             return false;
     39         }
     40 
     41         if (value.length() < 3) {
     42             return false;
     43         }
     44 
     45         if (!value.startsWith(HEX_PREFIX)) {
     46             return false;
     47         }
     48 
     49         // If TestRpc resolves the following issue, we can reinstate this code
     50         // https://github.com/ethereumjs/testrpc/issues/220
     51 //        if (value.length() > 3 && value.charAt(2) == '0') {
     52 //            return false;
     53 //        }
     54 
     55         return true;
     56     }
     57 
     58     public static String cleanHexPrefix(String input) {
     59         if (containsHexPrefix(input)) {
     60             return input.substring(2);
     61         } else {
     62             return input;
     63         }
     64     }
     65 
     66     public static String prependHexPrefix(String input) {
     67         if (!containsHexPrefix(input)) {
     68             return HEX_PREFIX + input;
     69         } else {
     70             return input;
     71         }
     72     }
     73 
     74     public static boolean containsHexPrefix(String input) {
     75         return input.length() > 1 && input.charAt(0) == '0' && input.charAt(1) == 'x';
     76     }
     77 
     78     public static BigInteger toBigInt(byte[] value, int offset, int length) {
     79         return toBigInt((Arrays.copyOfRange(value, offset, offset + length)));
     80     }
     81 
     82     public static BigInteger toBigInt(byte[] value) {
     83         return new BigInteger(1, value);
     84     }
     85 
     86     public static BigInteger toBigInt(String hexValue) {
     87         String cleanValue = cleanHexPrefix(hexValue);
     88         return new BigInteger(cleanValue, 16);
     89     }
     90 
     91     public static String toHexStringWithPrefix(BigInteger value) {
     92         return HEX_PREFIX + value.toString(16);
     93     }
     94 
     95     public static String toHexStringNoPrefix(BigInteger value) {
     96         return value.toString(16);
     97     }
     98 
     99     public static String toHexStringWithPrefixZeroPadded(BigInteger value, int size) {
    100         return toHexStringZeroPadded(value, size, true);
    101     }
    102 
    103     public static String toHexStringNoPrefixZeroPadded(BigInteger value, int size) {
    104         return toHexStringZeroPadded(value, size, false);
    105     }
    106 
    107     private static String toHexStringZeroPadded(BigInteger value, int size, boolean withPrefix) {
    108         String result = toHexStringNoPrefix(value);
    109 
    110         int length = result.length();
    111         if (length > size) {
    112             throw new UnsupportedOperationException(
    113                     "Value " + result + "is larger then length " + size);
    114         } else if (value.signum() < 0) {
    115             throw new UnsupportedOperationException("Value cannot be negative");
    116         }
    117 
    118         if (length < size) {
    119             result = Strings.zeros(size - length) + result;
    120         }
    121 
    122         if (withPrefix) {
    123             return HEX_PREFIX + result;
    124         } else {
    125             return result;
    126         }
    127     }
    128 
    129     public static byte[] toBytesPadded(BigInteger value, int length) {
    130         byte[] result = new byte[length];
    131         byte[] bytes = value.toByteArray();
    132 
    133         int bytesLength;
    134         int srcOffset;
    135         if (bytes[0] == 0) {
    136             bytesLength = bytes.length - 1;
    137             srcOffset = 1;
    138         } else {
    139              bytesLength = bytes.length;
    140             srcOffset = 0;
    141         }
    142 
    143         if (bytesLength > length) {
    144             throw new RuntimeException("Input is too large to put in byte array of size " + length);
    145         }
    146 
    147         int destOffset = length - bytesLength;
    148         System.arraycopy(bytes, srcOffset, result, destOffset, bytesLength);
    149         return result;
    150     }
    151 
    152     public static byte[] hexStringToByteArray(String input) {
    153         String cleanInput = cleanHexPrefix(input);
    154 
    155         int len = cleanInput.length();
    156 
    157         if (len == 0) {
    158             return new byte[] {};
    159         }
    160 
    161         byte[] data;
    162         int startIdx;
    163         if (len % 2 != 0) {
    164             data = new byte[(len / 2) + 1];
    165             data[0] = (byte) Character.digit(cleanInput.charAt(0), 16);
    166             startIdx = 1;
    167         } else {
    168             data = new byte[len / 2];
    169             startIdx = 0;
    170         }
    171 
    172         for (int i = startIdx; i < len; i += 2) {
    173             data[(i + 1) / 2] = (byte) ((Character.digit(cleanInput.charAt(i), 16) << 4)
    174                     + Character.digit(cleanInput.charAt(i+1), 16));
    175         }
    176         return data;
    177     }
    178 
    179     public static String toHexString(byte[] input, int offset, int length, boolean withPrefix) {
    180         StringBuilder stringBuilder = new StringBuilder();
    181         if (withPrefix) {
    182             stringBuilder.append("0x");
    183         }
    184         for (int i = offset; i < offset + length; i++) {
    185             stringBuilder.append(String.format("%02x", input[i] & 0xFF));
    186         }
    187 
    188         return stringBuilder.toString();
    189     }
    190 
    191     public static String toHexStringNoPrefix(byte[] input) {
    192         return toHexString(input, 0, input.length, false);
    193     }
    194 
    195     public static String toHexString(byte[] input) {
    196         return toHexString(input, 0, input.length, true);
    197     }
    198 
    199     public static byte b(int m, int n) {
    200         return (byte) ( (m << 4) | n);
    201     }
    202 
    203     public static boolean isIntegerValue(BigDecimal value) {
    204         return value.signum() == 0 ||
    205                 value.scale() <= 0 ||
    206                 value.stripTrailingZeros().scale() <= 0;
    207     }
    208 }
    View Code
    
    

    好了 这样 AES512 就实现了, 测试方法我在这就写了, 自己可以写个test 测试下。 


     

  • 相关阅读:
    基于SpringBoot打造在线教育系统(6)-- 二级分类模块UI篇
    基于SpringBoot打造在线教育系统(5)-- 课程分类模块
    基于SpringBoot打造在线教育系统(4)-- SpringBoot集成ElementUI
    基于SpringBoot打造在线教育系统(3)-- 登录与授权管理
    基于SpringBoot打造在线教育系统(2)-- 深入学习JPA与Junit测试
    我只会HelloWorld,但是我却完成了一个SpringBoot项目!(1)
    Constrast Learnning
    BlazePose: On-device Real-time Body Pose tracking
    pytest---fixture作用范围
    pytest---fixture中conftest.py文件
  • 原文地址:https://www.cnblogs.com/yueli/p/7478660.html
Copyright © 2011-2022 走看看