aes android,Android-AES加解密

1. AES(Advanced Encryption Standard) 介绍

AES 是比利时密码学家Joan Daemen和Vincent Rijmen所设计的一种加密算法,又称为 Rijndael 加密法。由美国国家标准与技术研究院(NIST)经过许多算法的筛选,高级加密标准(Advanced Encryption Standard)在2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准,在全世界被广泛使用。

AES 是一种对称加密算法,即使用秘钥加密数据以后,要使用相同的秘钥才能解密。AES 加密方式比 DES 加密更安全,但是速度比不上 DES,但在不同运行环境下能保持良好的性能。

AES 共有 5 种加密模式:

ECB(Electronic Code Book) 电子密码本模式

CBC(Cipher Block Chaining) 加密块链模式

CFB(Cipher FeedBack Mode) 加密反馈模式

OFB(Output FeedBack) 输出反馈模式

CTR(Counter) 计数器模式(不常见)

其中 ECB、CBC、CTR 为块加密模式,CFB、OFB 为流加密模式。

AES 五种加密模式: https://www.cnblogs.com/starwolf/p/3365834.html

2. AES 加解密

import android.util.Log;

import java.io.Closeable;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.nio.charset.Charset;

import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;

import javax.crypto.CipherInputStream;

import javax.crypto.CipherOutputStream;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

/**

* AES 对称加密算法,加解密工具类

*/

public class AESEncrypt {

private static final String TAG = AESEncrypt.class.getSimpleName() + " --> ";

/**

* 加密算法

*/

private static final String KEY_ALGORITHM = "AES";

/**

* AES 的 密钥长度,32 字节,范围:16 - 32 字节

*/

public static final int SECRET_KEY_LENGTH = 32;

/**

* 字符编码

*/

private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;

/**

* 秘钥长度不足 16 个字节时,默认填充位数

*/

private static final String DEFAULT_VALUE = "0";

/**

* 加解密算法/工作模式/填充方式

*/

private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

/**

* AES 加密

*

* @param data 待加密内容

* @param secretKey 加密密码,长度:16 或 32 个字符

* @return 返回Base64转码后的加密数据

*/

public static String encrypt(String data, String secretKey) {

try {

//创建密码器

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

//初始化为加密密码器

cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey));

byte[] encryptByte = cipher.doFinal(data.getBytes(CHARSET_UTF8));

// 将加密以后的数据进行 Base64 编码

return base64Encode(encryptByte);

} catch (Exception e) {

handleException(e);

}

return null;

}

/**

* AES 解密

*

* @param base64Data 加密的密文 Base64 字符串

* @param secretKey 解密的密钥,长度:16 或 32 个字符

*/

public static String decrypt(String base64Data, String secretKey) {

try {

byte[] data = base64Decode(base64Data);

Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

//设置为解密模式

cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey));

//执行解密操作

byte[] result = cipher.doFinal(data);

return new String(result, CHARSET_UTF8);

} catch (Exception e) {

handleException(e);

}

return null;

}

/**

* 使用密码获取 AES 秘钥

*/

public static SecretKeySpec getSecretKey(String secretKey) {

secretKey = toMakeKey(secretKey, SECRET_KEY_LENGTH, DEFAULT_VALUE);

return new SecretKeySpec(secretKey.getBytes(CHARSET_UTF8), KEY_ALGORITHM);

}

/**

* 如果 AES 的密钥小于 {@code length} 的长度,就对秘钥进行补位,保证秘钥安全。

*

* @param secretKey 密钥 key

* @param length 密钥应有的长度

* @param text 默认补的文本

* @return 密钥

*/

private static String toMakeKey(String secretKey, int length, String text) {

// 获取密钥长度

int strLen = secretKey.length();

// 判断长度是否小于应有的长度

if (strLen < length) {

// 补全位数

StringBuilder builder = new StringBuilder();

// 将key添加至builder中

builder.append(secretKey);

// 遍历添加默认文本

for (int i = 0; i < length - strLen; i++) {

builder.append(text);

}

// 赋值

secretKey = builder.toString();

}

return secretKey;

}

/**

* 将 Base64 字符串 解码成 字节数组

*/

public static byte[] base64Decode(String data) {

return Base64.decode(data, Base64.NO_WRAP);

}

/**

* 将 字节数组 转换成 Base64 编码

*/

public static String base64Encode(byte[] data) {

return Base64.encodeToString(data, Base64.NO_WRAP);

}

/**

* 处理异常

*/

private static void handleException(Exception e) {

e.printStackTrace();

Log.e(TAG, TAG + e);

}

}

3. AES 加解密文件

/**

* 对文件进行AES加密

*

* @param sourceFile 待加密文件

* @param dir 加密后的文件存储路径

* @param toFileName 加密后的文件名称

* @param secretKey 密钥

* @return 加密后的文件

*/

public static File encryptFile(File sourceFile, String dir, String toFileName, String secretKey) {

try {

// 创建加密后的文件

File encryptFile = new File(dir, toFileName);

// 根据文件创建输出流

FileOutputStream outputStream = new FileOutputStream(encryptFile);

// 初始化 Cipher

Cipher cipher = initFileAESCipher(secretKey, Cipher.ENCRYPT_MODE);

// 以加密流写入文件

CipherInputStream cipherInputStream = new CipherInputStream(

new FileInputStream(sourceFile), cipher);

// 创建缓存字节数组

byte[] buffer = new byte[1024 * 2];

// 读取

int len;

// 读取加密并写入文件

while ((len = cipherInputStream.read(buffer)) != -1) {

outputStream.write(buffer, 0, len);

outputStream.flush();

}

// 关闭加密输入流

cipherInputStream.close();

closeStream(outputStream);

return encryptFile;

} catch (Exception e) {

handleException(e);

}

return null;

}

/**

* AES解密文件

*

* @param sourceFile 源加密文件

* @param dir 解密后的文件存储路径

* @param toFileName 解密后的文件名称

* @param secretKey 密钥

*/

public static File decryptFile(File sourceFile, String dir, String toFileName, String secretKey) {

try {

// 创建解密文件

File decryptFile = new File(dir, toFileName);

// 初始化Cipher

Cipher cipher = initFileAESCipher(secretKey, Cipher.DECRYPT_MODE);

// 根据源文件创建输入流

FileInputStream inputStream = new FileInputStream(sourceFile);

// 获取解密输出流

CipherOutputStream cipherOutputStream = new CipherOutputStream(

new FileOutputStream(decryptFile), cipher);

// 创建缓冲字节数组

byte[] buffer = new byte[1024 * 2];

int len;

// 读取解密并写入

while ((len = inputStream.read(buffer)) >= 0) {

cipherOutputStream.write(buffer, 0, len);

cipherOutputStream.flush();

}

// 关闭流

cipherOutputStream.close();

closeStream(inputStream);

return decryptFile;

} catch (IOException e) {

handleException(e);

}

return null;

}

/**

* 初始化 AES Cipher

*

* @param secretKey 密钥

* @param cipherMode 加密模式

* @return 密钥

*/

private static Cipher initFileAESCipher(String secretKey, int cipherMode) {

try {

// 创建密钥规格

SecretKeySpec secretKeySpec = getSecretKey(secretKey);

// 获取密钥

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

// 初始化

cipher.init(cipherMode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));

return cipher;

} catch (Exception e) {

handleException(e);

}

return null;

}

/**

* 关闭流

*

* @param closeable 实现Closeable接口

*/

private static void closeStream(Closeable closeable) {

try {

if (closeable != null) closeable.close();

} catch (Exception e) {

handleException(e);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个简单的示例,展示了如何在 Android 中使用 AES 加密和解密文件: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.MessageDigest; import java.util.Arrays; public class AesUtil { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String SECRET_KEY = "my_secret_key"; private static final String IV = "my_initialization_vector"; public static void encrypt(String inputFile, String outputFile) throws Exception { SecretKeySpec secretKeySpec = generateKey(SECRET_KEY); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); FileInputStream inputStream = new FileInputStream(inputFile); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { byte[] output = cipher.update(buffer, 0, bytesRead); if (output != null) { outputStream.write(output); } } byte[] output = cipher.doFinal(); if (output != null) { outputStream.write(output); } inputStream.close(); outputStream.close(); } public static void decrypt(String inputFile, String outputFile) throws Exception { SecretKeySpec secretKeySpec = generateKey(SECRET_KEY); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); FileInputStream inputStream = new FileInputStream(inputFile); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { byte[] output = cipher.update(buffer, 0, bytesRead); if (output != null) { outputStream.write(output); } } byte[] output = cipher.doFinal(); if (output != null) { outputStream.write(output); } inputStream.close(); outputStream.close(); } private static SecretKeySpec generateKey(String key) throws Exception { byte[] keyBytes = key.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-256"); keyBytes = sha.digest(keyBytes); keyBytes = Arrays.copyOf(keyBytes, 16); return new SecretKeySpec(keyBytes, "AES"); } } ``` 在此示例中,我们使用 AES/CBC/PKCS5Padding 加密模式和 SHA-256 哈希算法生成密钥。我们将密钥和初始向量 IV 保存为常量,但您可以根据需要进行更改。 要使用此示例,请在您的代码中调用 `AesUtil.encrypt(inputFile, outputFile)` 或 `AesUtil.decrypt(inputFile, outputFile)` 方法,其中 `inputFile` 是要加密或解密的文件路径,而 `outputFile` 是加密或解密后的文件路径。 请注意,此示例中的加密和解密操作是阻塞的,并且使用了相对较小的缓冲区。对于大文件和需要异步处理的情况,您需要进行适当的优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值