Android AES加解密
工具类
/** * 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(); } } }
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android多线程之Handler、Looper与MessageQueue源码解析
本文的目的是来分析下 Android 系统中以 Handler、Looper、MessageQueue 组成的异步消息处理机制,通过源码来了解整个消息处理流程的走向以及相关三者之间的关系 需要先了解以下几个预备知识 Handler:UI 线程或者子线程通过 Handler 向 MessageQueue(消息队列) 发送 Message MessageQueue:通过 Handler 发送的消息并非是立即执行的,需要存入一个消息队列中来依次执行 Looper:Looper 不断从 MessageQueue 中获取消息并将之传递给消息处理者(即是消息发送者 Handler 本身)进行处理 互斥机制:可能会有多条线程(1条 UI 线程,n 条子线程)向同一个消息队列插入消息,此时就需要进行同步 Handler 发送消息的形式主要有以下几种形式,其最终调用的都是 sendMessageAtTime() 方法 public final boolean sendMessage(Message msg){ return sendMessageDelayed(msg, 0); } public fin...
- 下一篇
Android在Application层级维护和管理全局所有Activity的方法ActivityLifecycleCallbacks
Android在Application层级维护和管理全局所有Activity的方法ActivityLifecycleCallbacks 经常看到有些项目中经常性的把所有activity继承自一个base的Activity,然后在每一次启动新activity时候添加当前activity到一个全局List那样的列表中,已达到全局管理和维护activity的目的,这种做法大概是四五年前的技术解决方案。如今谷歌Android官方推出了ActivityLifecycleCallbacks,ActivityLifecycleCallbacks是在Application层级的接口回调,App中所有的任何一个Activity的生命周期方法被触发时候,都会进入相应的ActivityLifecycleCallbacks生命周期里面,例如: package zhangphil.test; import android.app.Activity; import android.app.Application; import android.os.Bundle; import com.orhanobut.log...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境