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 测试下。 


 

posted @ 2017-09-05 14:59  阅历笔记  阅读(2374)  评论(0编辑  收藏  举报