Java AES512加密算法

来源:互联网 发布:房子短租软件 编辑:程序博客网 时间:2024/06/15 06:30

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 加密方法

package org.message.encrypt.cipher;import java.io.UnsupportedEncodingException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import org.message.encrypt.tool.Encode;import org.message.encrypt.tool.Numeric;import com.google.common.io.BaseEncoding;public class AESCipher {private static final String ALGORITHM_AES256 = "AES/CBC/PKCS5Padding";// "AES/CBC/PKCS7Padding";private final SecretKeySpec secretKeySpec;private static final String CHARSET = "UTF-8";private static final String DEFAULT_IV = "iv is default value";private Cipher cipher;private IvParameterSpec iv;public AESCipher(String key) {this(key, DEFAULT_IV);}public AESCipher(String key, String iv) {this(Numeric.hexStringToByteArray(key), Numeric.hexStringToByteArray(iv));}private AESCipher(byte[] key, byte[] iv) {// Security.addProvider(new BouncyCastleProvider());if (null == key || key.length != 32) {throw new RuntimeException("input params key must be 32bit bytes array");}if (null == iv || iv.length != 16) {throw new RuntimeException("input params iv must be 16bit bytes array");}this.secretKeySpec = new SecretKeySpec(key, "AES");this.iv = new IvParameterSpec(iv);try {this.cipher = Cipher.getInstance(ALGORITHM_AES256);} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new RuntimeException("instantiation objects Cipher exception");}}/** * AES Encrypt algorithm *  * @param encryptSource *            not null string * @return after AES encrypt result , the type of the string */public String getEncryptedMessage(final String encryptSource) {Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);byte[] encryptedTextBytes = null;try {encryptedTextBytes = cipher.doFinal(encryptSource.getBytes(CHARSET));} catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {throw new RuntimeException("AES encrypt exception");}return Encode.baseEncode(encryptedTextBytes);}/** * AES decrypt algorithm *  * @param decryptSource *            AES encrypted cipher, type of String * @return decrypted plaintext, type of string */public String getDecryptMessage(String decryptSource) {Cipher cipher = getCipher(Cipher.DECRYPT_MODE);byte[] encryptedTextBytes = null;String decryptResult = null;try {encryptedTextBytes = cipher.doFinal(BaseEncoding.base64().decode(decryptSource));} catch (IllegalBlockSizeException | BadPaddingException e) {throw new RuntimeException("AES decrypt exception");}try {decryptResult = new String(encryptedTextBytes, CHARSET);} catch (UnsupportedEncodingException e) {throw new RuntimeException("bytes array convert into string exception");}return decryptResult;}private Cipher getCipher(int encryptMode) {try {cipher.init(encryptMode, secretKeySpec, iv);} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {throw new RuntimeException("init objects Cipher exception");}return cipher;}}


Encode 工具类

package org.message.encrypt.tool;import com.google.common.io.BaseEncoding;public class Encode {/** * byte[] convert into string ,use base encode default value BASE64 *  * @param encodeMassage *            not null byte[] * @return after encode result */public static String baseEncode(final byte[] encodeMassage) {return baseEncode(encodeMassage, BaseType.BASE64);}/** * byte[] convert into string ,use base encode default value BASE64 *  * @param encodeMassage *            not null byte[] * @param encoder *            of type please see enum type of inner class , the class name *            'BaseType' * @return after encode result , the type of string */public static String baseEncode(final byte[] encodeMassage, final BaseType encoder) {String baseResult = null;switch (encoder) {case BASE64:baseResult = BaseEncoding.base64().encode(encodeMassage);break;case BASE32:baseResult = BaseEncoding.base32().encode(encodeMassage);break;case BASE32HEX:baseResult = BaseEncoding.base32Hex().encode(encodeMassage);break;case BASE16:baseResult = BaseEncoding.base16().encode(encodeMassage);break;default:break;}return baseResult;}/** * string convert into byte[], use base decode *  * @param decodeMassage *            not null string * @return after decode result , the type of byte[] */public static byte[] baseDecode(final String decodeMassage) {return baseDecode(decodeMassage, BaseType.BASE64);}public static byte[] baseDecode(final String decodeMassage, final BaseType encoder) {byte[] baseResult = null;switch (encoder) {case BASE64:baseResult = BaseEncoding.base64().decode(decodeMassage);break;case BASE32:baseResult = BaseEncoding.base32().decode(decodeMassage);break;case BASE32HEX:baseResult = BaseEncoding.base32Hex().decode(decodeMassage);break;case BASE16:baseResult = BaseEncoding.base16().decode(decodeMassage);break;default:break;}return baseResult;}enum BaseType {BASE64, BASE32, BASE32HEX, BASE16;}}


Numeric 工具类

package org.message.encrypt.tool;import java.math.BigDecimal;import java.math.BigInteger;import java.util.Arrays;/** * <p>Message codec functions.</p> * * <p>Implementation as per https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding</p> */public final class Numeric {    private static final String HEX_PREFIX = "0x";    private Numeric() {    }    public static String encodeQuantity(BigInteger value) {        if (value.signum() != -1) {            return HEX_PREFIX + value.toString(16);        } else {            throw new RuntimeException("Negative values are not supported");        }    }    public static BigInteger decodeQuantity(String value) {        if (!isValidHexQuantity(value)) {            throw new RuntimeException("Value must be in format 0x[1-9]+[0-9]* or 0x0");        }        try {            return new BigInteger(value.substring(2), 16);        } catch (NumberFormatException e) {            throw new RuntimeException("Negative ", e);        }    }    private static boolean isValidHexQuantity(String value) {        if (value == null) {            return false;        }        if (value.length() < 3) {            return false;        }        if (!value.startsWith(HEX_PREFIX)) {            return false;        }        // If TestRpc resolves the following issue, we can reinstate this code        // https://github.com/ethereumjs/testrpc/issues/220//        if (value.length() > 3 && value.charAt(2) == '0') {//            return false;//        }        return true;    }    public static String cleanHexPrefix(String input) {        if (containsHexPrefix(input)) {            return input.substring(2);        } else {            return input;        }    }    public static String prependHexPrefix(String input) {        if (!containsHexPrefix(input)) {            return HEX_PREFIX + input;        } else {            return input;        }    }    public static boolean containsHexPrefix(String input) {        return input.length() > 1 && input.charAt(0) == '0' && input.charAt(1) == 'x';    }    public static BigInteger toBigInt(byte[] value, int offset, int length) {        return toBigInt((Arrays.copyOfRange(value, offset, offset + length)));    }    public static BigInteger toBigInt(byte[] value) {        return new BigInteger(1, value);    }    public static BigInteger toBigInt(String hexValue) {        String cleanValue = cleanHexPrefix(hexValue);        return new BigInteger(cleanValue, 16);    }    public static String toHexStringWithPrefix(BigInteger value) {        return HEX_PREFIX + value.toString(16);    }    public static String toHexStringNoPrefix(BigInteger value) {        return value.toString(16);    }    public static String toHexStringWithPrefixZeroPadded(BigInteger value, int size) {        return toHexStringZeroPadded(value, size, true);    }    public static String toHexStringNoPrefixZeroPadded(BigInteger value, int size) {        return toHexStringZeroPadded(value, size, false);    }    private static String toHexStringZeroPadded(BigInteger value, int size, boolean withPrefix) {        String result = toHexStringNoPrefix(value);        int length = result.length();        if (length > size) {            throw new UnsupportedOperationException(                    "Value " + result + "is larger then length " + size);        } else if (value.signum() < 0) {            throw new UnsupportedOperationException("Value cannot be negative");        }        if (length < size) {            result = Strings.zeros(size - length) + result;        }        if (withPrefix) {            return HEX_PREFIX + result;        } else {            return result;        }    }    public static byte[] toBytesPadded(BigInteger value, int length) {        byte[] result = new byte[length];        byte[] bytes = value.toByteArray();        int bytesLength;        int srcOffset;        if (bytes[0] == 0) {            bytesLength = bytes.length - 1;            srcOffset = 1;        } else {             bytesLength = bytes.length;            srcOffset = 0;        }        if (bytesLength > length) {            throw new RuntimeException("Input is too large to put in byte array of size " + length);        }        int destOffset = length - bytesLength;        System.arraycopy(bytes, srcOffset, result, destOffset, bytesLength);        return result;    }    public static byte[] hexStringToByteArray(String input) {        String cleanInput = cleanHexPrefix(input);        int len = cleanInput.length();        if (len == 0) {            return new byte[] {};        }        byte[] data;        int startIdx;        if (len % 2 != 0) {            data = new byte[(len / 2) + 1];            data[0] = (byte) Character.digit(cleanInput.charAt(0), 16);            startIdx = 1;        } else {            data = new byte[len / 2];            startIdx = 0;        }        for (int i = startIdx; i < len; i += 2) {            data[(i + 1) / 2] = (byte) ((Character.digit(cleanInput.charAt(i), 16) << 4)                    + Character.digit(cleanInput.charAt(i+1), 16));        }        return data;    }    public static String toHexString(byte[] input, int offset, int length, boolean withPrefix) {        StringBuilder stringBuilder = new StringBuilder();        if (withPrefix) {            stringBuilder.append("0x");        }        for (int i = offset; i < offset + length; i++) {            stringBuilder.append(String.format("%02x", input[i] & 0xFF));        }        return stringBuilder.toString();    }    public static String toHexStringNoPrefix(byte[] input) {        return toHexString(input, 0, input.length, false);    }    public static String toHexString(byte[] input) {        return toHexString(input, 0, input.length, true);    }    public static byte b(int m, int n) {        return (byte) ( (m << 4) | n);    }    public static boolean isIntegerValue(BigDecimal value) {        return value.signum() == 0 ||                value.scale() <= 0 ||                value.stripTrailingZeros().scale() <= 0;    }}


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


 

2 0
原创粉丝点击