您现在的位置是:首页 > 文章详情

Android AES加解密

日期:2018-06-21点击:299

工具类

/** * AES加解密工具类, 使用Base64进行编解码 * String value = AESUtil.encrypt("mazaiting", "123456789"); Log.e("MainActivity", value); Log.e("MainActivity", AESUtil.decrypt("mazaiting", value)); * Created by mazaiting on 2018/6/22. */ public class AESUtil { /**密钥长度*/ private static final int KEY_LENGTH = 16; /**默认填充位数*/ private static final String DEFAULT_VALUE = "0"; /** * 加密 * @param key 密钥 * @param src 加密文本 * @return 加密后的文本 * @throws Exception */ public static String encrypt(String key, String src) throws Exception { // 对源数据进行Base64编码 src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT); // 补全KEY为16位 byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes(); // 获取加密后的字节数组 byte[] result = getBytes(rawKey, src.getBytes("utf-8"), Cipher.ENCRYPT_MODE); // 对加密后的字节数组进行Base64编码 result = Base64.encode(result, Base64.DEFAULT); // 返回字符串 return new String(result, Charset.defaultCharset()); } /** * 解密 * @param key 密钥 * @param encrypted 待解密文本 * @return 返回解密后的数据 * @throws Exception */ public static String decrypt(String key, String encrypted) throws Exception { // 补全KEY为16位 byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes(); // 获取加密后的二进制字节数组 byte[] enc = encrypted.getBytes(Charset.defaultCharset()); // 对二进制数组进行Base64解码 enc = Base64.decode(enc, Base64.DEFAULT); // 获取解密后的二进制字节数组 byte[] result = getBytes(rawKey, enc, Cipher.DECRYPT_MODE); // 对解密后的二进制数组进行Base64解码 result = Base64.decode(result, Base64.DEFAULT); // 返回字符串 return new String(result, "utf-8"); } /** * 密钥key ,默认补的数字,补全16位数,以保证安全补全至少16位长度,android和ios对接通过 * @param key 密钥key * @param length 密钥应有的长度 * @param text 默认补的文本 * @return 密钥 */ private static String toMakeKey(String key, int length, String text) { // 获取密钥长度 int strLen = key.length(); // 判断长度是否小于应有的长度 if (strLen < length) { // 补全位数 StringBuilder builder = new StringBuilder(); // 将key添加至builder中 builder.append(key); // 遍历添加默认文本 for (int i = 0; i < length - strLen; i++) { builder.append(text); } // 赋值 key = builder.toString(); } return key; } /** * 加解密过程 * 1. 通过密钥得到一个密钥专用的对象SecretKeySpec * 2. Cipher 加密算法,加密模式和填充方式三部分或指定加密算 (可以只用写算法然后用默认的其他方式)Cipher.getInstance("AES"); * @param key 二进制密钥数组 * @param src 加解密的源二进制数据 * @param mode 模式,加密为:Cipher.ENCRYPT_MODE;解密为:Cipher.DECRYPT_MODE * @return 加解密后的二进制数组 * @throws NoSuchAlgorithmException 无效算法 * @throws NoSuchPaddingException 无效填充 * @throws InvalidKeyException 无效KEY * @throws InvalidAlgorithmParameterException 无效密钥 * @throws IllegalBlockSizeException 非法块字节 * @throws BadPaddingException 坏数据 */ private static byte[] getBytes(byte[] key, byte[] src, int mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { // 密钥规格 SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); // 密钥实例 Cipher cipher = Cipher.getInstance("AES"); // 初始化密钥模式 cipher.init(mode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); // 加密数据 return cipher.doFinal(src); } } 

使用

 String value = AESUtil.encrypt("mazaiting", "123456789"); Log.e("MainActivity", value); Log.e("MainActivity", AESUtil.decrypt("mazaiting", value)); 

加密文件及字符串工具类

/** * Aes加密工具类 * 使用: * val value = AESUtil.encrypt("mazaiting", "123456789") Log.e("MainActivity", value) Log.e("MainActivity", AESUtil.decrypt("mazaiting", value)) * * Created by mazaiting on 2018/6/21. */ public class AESUtil { /**16进制数*/ private final static String HEX = "0123456789ABCDEF"; /**密钥长度*/ private static final int KEY_LENGTH = 16; /**默认填充位数*/ private static final String DEFAULT_VALUE = "0"; /** * 加密 * @param key 密钥 * @param src 加密文本 * @return 加密后的文本 * @throws Exception */ public static String encrypt(String key, String src) throws Exception { // 对源数据进行Base64编码 src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT); // 补全KEY为16位 byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes(); // 获取加密后的字节数组 byte[] result = getBytes(rawKey, src.getBytes("utf-8"),"AES", Cipher.ENCRYPT_MODE); // 对加密后的字节数组进行Base64编码 result = Base64.encode(result, Base64.DEFAULT); // 返回字符串 return new String(result, Charset.defaultCharset()); } /** * 解密 * @param key 密钥 * @param encrypted 待解密文本 * @return 返回解密后的数据 * @throws Exception */ public static String decrypt(String key, String encrypted) throws Exception { // 补全KEY为16位 byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes(); // 获取加密后的二进制字节数组 byte[] enc = encrypted.getBytes(Charset.defaultCharset()); // 对二进制数组进行Base64解码 enc = Base64.decode(enc, Base64.DEFAULT); // 获取解密后的二进制字节数组 byte[] result = getBytes(rawKey, enc,"AES", Cipher.DECRYPT_MODE); // 对解密后的二进制数组进行Base64解码 result = Base64.decode(result, Base64.DEFAULT); // 返回字符串 return new String(result, "utf-8"); } /** * 加密 * @param key 密钥 * @param src 加密文本 * @return 加密后的数据 * @throws Exception */ public static String encrypt2Java(String key, String src) throws Exception { // /src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT); byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();// key.getBytes(); // byte[] result = encrypt2Java(rawKey, src.getBytes("utf-8")); byte[] result = getBytes(rawKey, src.getBytes("utf-8"), "AES/CBC/PKCS5Padding", Cipher.ENCRYPT_MODE); // result = Base64.encode(result, Base64.DEFAULT); return toHex(result); } /** * 加密 * @param key 密钥 * @param src 加密文本 * @return 加密后的数据 * @throws Exception */ public static String decrypt2Java(String key, String src) throws Exception { // /src = Base64.encodeToString(src.getBytes(), Base64.DEFAULT); byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes();// key.getBytes(); byte[] result = getBytes(rawKey, src.getBytes("utf-8"), "AES/CBC/PKCS5Padding", Cipher.DECRYPT_MODE); // result = Base64.encode(result, Base64.DEFAULT); return toHex(result); } /** * 密钥key ,默认补的数字,补全16位数,以保证安全补全至少16位长度,android和ios对接通过 * @param key 密钥key * @param length 密钥应有的长度 * @param text 默认补的文本 * @return 密钥 */ private static String toMakeKey(String key, int length, String text) { // 获取密钥长度 int strLen = key.length(); // 判断长度是否小于应有的长度 if (strLen < length) { // 补全位数 StringBuilder builder = new StringBuilder(); // 将key添加至builder中 builder.append(key); // 遍历添加默认文本 for (int i = 0; i < length - strLen; i++) { builder.append(text); } // 赋值 key = builder.toString(); } return key; } /** * 加解密过程 * 1. 通过密钥得到一个密钥专用的对象SecretKeySpec * 2. Cipher 加密算法,加密模式和填充方式三部分或指定加密算 (可以只用写算法然后用默认的其他方式)Cipher.getInstance("AES"); * @param key 二进制密钥数组 * @param src 加解密的源二进制数据 * @param mode 模式,加密为:Cipher.ENCRYPT_MODE;解密为:Cipher.DECRYPT_MODE * @return 加解密后的二进制数组 * @throws NoSuchAlgorithmException 无效算法 * @throws NoSuchPaddingException 无效填充 * @throws InvalidKeyException 无效KEY * @throws InvalidAlgorithmParameterException 无效密钥 * @throws IllegalBlockSizeException 非法块字节 * @throws BadPaddingException 坏数据 */ private static byte[] getBytes(byte[] key, byte[] src,String transformation, int mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { // 密钥规格 SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); // 密钥实例 Cipher cipher = Cipher.getInstance(transformation); // 初始化密钥模式 cipher.init(mode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); // 加密数据 return cipher.doFinal(src); } /**获取16进制字符串*/ public static String toHex(String txt) { return toHex(txt.getBytes()); } /**将16进制字符串转换为未编码后的数据*/ public static String fromHex(String hex) { return new String(toByte(hex)); } /** * 把16进制转化为字节数组 * @param hexString 16进制字符串 * @return 加密后的字节数组 */ private static byte[] toByte(String hexString) { // 获取源数据长度 int len = hexString.length() / 2; // 创建字节数组 byte[] result = new byte[len]; // 遍历 for (int i = 0; i < len; i++) result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue(); // 返回二进制字节数组 return result; } /** * 二进制转字符,转成了16进制 * 0123456789abcdef * @param bytes 字节组数 * @return 16进制编码的字符串 */ private static String toHex(byte[] bytes) { // 判断二进制数组长度是否小于0 if (bytes.length <= 0) return ""; // 创建字符串连接对象 StringBuilder builder = new StringBuilder(2 * bytes.length); for (byte b : bytes) { // 拼接字符 builder.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); } // 返回字符串 return builder.toString(); } /** * 对文件进行AES加密 * @param sourceFile 待加密文件 * @param toFile 加密后的文件 * @param dir 文件存储路径 * @param key 密钥 * @return 加密后的文件 */ public static File encryptFile(File sourceFile, String toFile, String dir, String key) { // 新建临时加密文件 File encryptFile = null; // 输入流 InputStream inputStream = null; // 输出流 OutputStream outputStream = null; try { // 读取源文件,创建文件输入流 inputStream = new FileInputStream(sourceFile); // 创建加密后的文件 encryptFile = new File(dir + toFile); // 根据文件创建输出流 outputStream = new FileOutputStream(encryptFile); // 初始化 Cipher Cipher cipher = initAESCipher(key, Cipher.ENCRYPT_MODE); // 以加密流写入文件 CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher); // 创建缓存字节数组 byte[] cache = new byte[1024]; // 读取 int len; // 读取加密并写入文件 while ((len = cipherInputStream.read(cache)) != -1) { outputStream.write(cache, 0, len); outputStream.flush(); } // 关闭加密输入流 cipherInputStream.close(); } catch (IOException e) { e.printStackTrace(); } finally { closeStream(inputStream); closeStream(outputStream); } return encryptFile; } /** * AES方式解密文件 * @param sourceFile 源文件 * @param toFile 目标文件 * @param dir 文件存储路径 * @param key 密钥 * @return */ public static File decryptFile(File sourceFile, String toFile, String dir, String key) { // 解密文件 File decryptFile = null; // 文件输入流 InputStream inputStream = null; // 文件输出流 OutputStream outputStream = null; try { // 创建解密文件 decryptFile = new File(dir + toFile); // 初始化Cipher Cipher cipher = initAESCipher(key, Cipher.DECRYPT_MODE); // 根据源文件创建输入流 inputStream = new FileInputStream(sourceFile); // 创建输出流 outputStream = new FileOutputStream(decryptFile); // 获取解密输出流 CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher); // 创建缓冲字节数组 byte[] buffer = new byte[1024]; int len; // 读取解密并写入 while ((len = inputStream.read(buffer)) >= 0) { cipherOutputStream.write(buffer, 0, len); cipherOutputStream.flush(); } // 关闭流 cipherOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } finally { closeStream(inputStream); closeStream(outputStream); } return decryptFile; } /** * 初始化 AES Cipher * @param key 密钥 * @param cipherMode 加密模式 * @return 密钥 */ private static Cipher initAESCipher(String key, int cipherMode) { Cipher cipher = null; try { // 将KEY进行修正 byte[] rawKey = toMakeKey(key, KEY_LENGTH, DEFAULT_VALUE).getBytes(); // 创建密钥规格 SecretKeySpec secretKeySpec = new SecretKeySpec(rawKey, "AES"); // 获取密钥 cipher = Cipher.getInstance("AES"); // 初始化 cipher.init(cipherMode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | InvalidKeyException e) { e.printStackTrace(); } return cipher; } /** * 关闭流 * @param closeable 实现Closeable接口 */ private static void closeStream(Closeable closeable) { try { closeable.close(); } catch (IOException e) { e.printStackTrace(); } } } 
原文链接:https://yq.aliyun.com/articles/663299
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章