android 安全之——文件加密AES加密算法、
2016-12-22 14:28
127 查看
AES加密算法是目前比较流行加密方式,目前还没有针对AES有效的破解方式,比较靠谱。AES又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
AES加密数据块和密钥长度可以是128比特、192比特、256比特中的任意一个。
AES加密有很多轮的重复和变换。大致步骤如下:
1、密钥扩展(KeyExpansion),
2、初始轮(Initial Round),
3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,
4、最终轮(Final Round),最终轮没有MixColumns。
jdk中算法的支持:
密钥长度:128位
工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128
填充方式:Nopadding/PKCS5Padding/ISO10126Padding/
这里需要注意一个问题,在创建Cipher对象是需要一个第三方Provider来提供算法实现,在标准JDK中只是规定了JCE(JCE (Java Cryptography
Extension) 是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。)接口,但是内部实现需要自己或者第三方提供,因此我们这里使用bouncycastle的开源的JCE实现包,下载地址:http://bouncycastle.org/latest_releases.html,我使用的是bcprov-jdk15on-150.jar jdk1.6。
下面是Android中一种实现方式:
[java] view
plain copy
public class AESKeyModel {
public static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
private String srcFile="",destionFile="";
/**
* 初始化密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public byte[] initSecretKey() {
//返回生成指定算法的秘密密钥的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return new byte[0];
}
//初始化此密钥生成器,使其具有确定的密钥大小
//AES 要求密钥长度为 128
kg.init(128);
//生成一个密钥
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
public void setDestionFile(String destionFile) {
this.destionFile = destionFile;
}
public void setSrcFile(String srcFile) {
this.srcFile = srcFile;
}
/**
* 转换密钥
*
* @param key 二进制密钥
* @return 密钥
*/
private static Key toKey(byte[] key){
//生成密钥
return new SecretKeySpec(key, KEY_ALGORITHM);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,Key key) throws Exception{
return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 二进制密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 二进制密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{
//还原密钥
Key k = toKey(key);
return encrypt(data, k, cipherAlgorithm);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{
//实例化
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
//使用密钥初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
//执行操作
return cipher.doFinal(data);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 二进制密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,Key key) throws Exception{
return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 二进制密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{
//还原密钥
Key k = toKey(key);
return decrypt(data, k, cipherAlgorithm);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{
//实例化
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key);
//执行操作
return cipher.doFinal(data);
}
public void encryptionFile(Key sessionKey) throws Exception {
int len = 0;
byte[] buffer = new byte[5 * 1024];
byte[] cipherbuffer = null;
// 使用会话密钥对文件加密。
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM,new BouncyCastleProvider());
IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes());
cipher.init(Cipher.ENCRYPT_MODE, sessionKey,iv);
FileInputStream fis = new FileInputStream(new File(srcFile));
FileOutputStream fos = new FileOutputStream(new File(destionFile));
// 读取原文,加密并写密文到输出文件。
while ((len = fis.read(buffer)) != -1) {
cipherbuffer = cipher.update(buffer, 0, len);
fos.write(cipherbuffer);
fos.flush();
}
cipherbuffer = cipher.doFinal();
fos.write(cipherbuffer);
fos.flush();
if (fis != null)
fis.close();
if (fos != null)
fos.close();
}
public void descryptionFile(Key sessionKey) throws Exception{
int len = 0;
byte[] buffer = new byte[5 * 1024];
byte[] plainbuffer = null;
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM,new BouncyCastleProvider());
IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes());
cipher.init(Cipher.DECRYPT_MODE,sessionKey,iv);
FileInputStream fis = new FileInputStream(new File(srcFile));
FileOutputStream fos = new FileOutputStream(new File(destionFile));
while ((len = fis.read(buffer)) != -1){
plainbuffer = cipher.update(buffer,0,len);
fos.write(plainbuffer);
fos.flush();
}
plainbuffer = cipher.doFinal();
fos.write(plainbuffer);
fos.flush();
if(fis!=null)
fis.close();
if(fos!=null)
fos.close();
}
}
加密文件:
Key key_AES;
private srcjiamiFile,outjiemiFile;
[java] view
plain copy
void testAESJia(String srcPath){
File f=new File(srcPath);
if(!f.exists()||f.isDirectory())
Toast.makeText(getApplicationContext(), "该文件不合法!", Toast.LENGTH_SHORT).show();
else{
String prefix=f.getName().substring(0, f.getName().indexOf('.'));
String suffix=f.getName().substring(f.getName().indexOf('.'));
srcjiamiFile=Environment.getExternalStorageDirectory()+File.separator+prefix+"AES_jiAMi"+suffix;
AESKeyModel model_aes=new AESKeyModel();
model_aes.setSrcFile(srcPath);
model_aes.setDestionFile(srcjiamiFile);
try {
key_AES=new SecretKeySpec(model_aes.initSecretKey(),AESKeyModel.KEY_ALGORITHM);
model_aes.encryptionFile(key_AES);
} catch (Exception e) {
e.printStackTrace();
}
}
}
解密文件:
[java] view
plain copy
void testAESJieMi(String JiamiFilePath){
File f=new File(JiamiFilePath);
if(!f.exists()||f.isDirectory())
Toast.makeText(getApplicationContext(), "该文件不合法!", Toast.LENGTH_SHORT).show();
else{
String prefix=f.getName().substring(0, f.getName().indexOf('.'));
String suffix=f.getName().substring(f.getName().indexOf('.'));
outjiemiFile=Environment.getExternalStorageDirectory()+File.separator+prefix+"AES_jieMi"+suffix;
AESKeyModel model_aes=new AESKeyModel();
model_aes.setSrcFile(JiamiFilePath);
model_aes.setDestionFile(outjiemiFile);
try {
model_aes.descryptionFile(key_AES);
} catch (Exception e) {
e.printStackTrace();
}
}
}
AES加密数据块和密钥长度可以是128比特、192比特、256比特中的任意一个。
AES加密有很多轮的重复和变换。大致步骤如下:
1、密钥扩展(KeyExpansion),
2、初始轮(Initial Round),
3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,
4、最终轮(Final Round),最终轮没有MixColumns。
jdk中算法的支持:
密钥长度:128位
工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128
填充方式:Nopadding/PKCS5Padding/ISO10126Padding/
这里需要注意一个问题,在创建Cipher对象是需要一个第三方Provider来提供算法实现,在标准JDK中只是规定了JCE(JCE (Java Cryptography
Extension) 是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。)接口,但是内部实现需要自己或者第三方提供,因此我们这里使用bouncycastle的开源的JCE实现包,下载地址:http://bouncycastle.org/latest_releases.html,我使用的是bcprov-jdk15on-150.jar jdk1.6。
下面是Android中一种实现方式:
[java] view
plain copy
public class AESKeyModel {
public static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
private String srcFile="",destionFile="";
/**
* 初始化密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public byte[] initSecretKey() {
//返回生成指定算法的秘密密钥的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return new byte[0];
}
//初始化此密钥生成器,使其具有确定的密钥大小
//AES 要求密钥长度为 128
kg.init(128);
//生成一个密钥
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
public void setDestionFile(String destionFile) {
this.destionFile = destionFile;
}
public void setSrcFile(String srcFile) {
this.srcFile = srcFile;
}
/**
* 转换密钥
*
* @param key 二进制密钥
* @return 密钥
*/
private static Key toKey(byte[] key){
//生成密钥
return new SecretKeySpec(key, KEY_ALGORITHM);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,Key key) throws Exception{
return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 二进制密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 二进制密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{
//还原密钥
Key k = toKey(key);
return encrypt(data, k, cipherAlgorithm);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{
//实例化
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
//使用密钥初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
//执行操作
return cipher.doFinal(data);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 二进制密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,Key key) throws Exception{
return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 二进制密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{
//还原密钥
Key k = toKey(key);
return decrypt(data, k, cipherAlgorithm);
}
/**
* 解密
*
* @param data 待解密数据
* @param key 密钥
* @param cipherAlgorithm 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{
//实例化
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key);
//执行操作
return cipher.doFinal(data);
}
public void encryptionFile(Key sessionKey) throws Exception {
int len = 0;
byte[] buffer = new byte[5 * 1024];
byte[] cipherbuffer = null;
// 使用会话密钥对文件加密。
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM,new BouncyCastleProvider());
IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes());
cipher.init(Cipher.ENCRYPT_MODE, sessionKey,iv);
FileInputStream fis = new FileInputStream(new File(srcFile));
FileOutputStream fos = new FileOutputStream(new File(destionFile));
// 读取原文,加密并写密文到输出文件。
while ((len = fis.read(buffer)) != -1) {
cipherbuffer = cipher.update(buffer, 0, len);
fos.write(cipherbuffer);
fos.flush();
}
cipherbuffer = cipher.doFinal();
fos.write(cipherbuffer);
fos.flush();
if (fis != null)
fis.close();
if (fos != null)
fos.close();
}
public void descryptionFile(Key sessionKey) throws Exception{
int len = 0;
byte[] buffer = new byte[5 * 1024];
byte[] plainbuffer = null;
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM,new BouncyCastleProvider());
IvParameterSpec iv = new IvParameterSpec("0000000000123456".getBytes());
cipher.init(Cipher.DECRYPT_MODE,sessionKey,iv);
FileInputStream fis = new FileInputStream(new File(srcFile));
FileOutputStream fos = new FileOutputStream(new File(destionFile));
while ((len = fis.read(buffer)) != -1){
plainbuffer = cipher.update(buffer,0,len);
fos.write(plainbuffer);
fos.flush();
}
plainbuffer = cipher.doFinal();
fos.write(plainbuffer);
fos.flush();
if(fis!=null)
fis.close();
if(fos!=null)
fos.close();
}
}
加密文件:
Key key_AES;
private srcjiamiFile,outjiemiFile;
[java] view
plain copy
void testAESJia(String srcPath){
File f=new File(srcPath);
if(!f.exists()||f.isDirectory())
Toast.makeText(getApplicationContext(), "该文件不合法!", Toast.LENGTH_SHORT).show();
else{
String prefix=f.getName().substring(0, f.getName().indexOf('.'));
String suffix=f.getName().substring(f.getName().indexOf('.'));
srcjiamiFile=Environment.getExternalStorageDirectory()+File.separator+prefix+"AES_jiAMi"+suffix;
AESKeyModel model_aes=new AESKeyModel();
model_aes.setSrcFile(srcPath);
model_aes.setDestionFile(srcjiamiFile);
try {
key_AES=new SecretKeySpec(model_aes.initSecretKey(),AESKeyModel.KEY_ALGORITHM);
model_aes.encryptionFile(key_AES);
} catch (Exception e) {
e.printStackTrace();
}
}
}
解密文件:
[java] view
plain copy
void testAESJieMi(String JiamiFilePath){
File f=new File(JiamiFilePath);
if(!f.exists()||f.isDirectory())
Toast.makeText(getApplicationContext(), "该文件不合法!", Toast.LENGTH_SHORT).show();
else{
String prefix=f.getName().substring(0, f.getName().indexOf('.'));
String suffix=f.getName().substring(f.getName().indexOf('.'));
outjiemiFile=Environment.getExternalStorageDirectory()+File.separator+prefix+"AES_jieMi"+suffix;
AESKeyModel model_aes=new AESKeyModel();
model_aes.setSrcFile(JiamiFilePath);
model_aes.setDestionFile(outjiemiFile);
try {
model_aes.descryptionFile(key_AES);
} catch (Exception e) {
e.printStackTrace();
}
}
}
相关文章推荐
- [置顶] Android应用安全隐患现状,资源文件加密/安全防护进化史
- 文件加密保卫中小企业信息安全
- 域环境下如何保护重要资料文件的安全(一)---EFS加密(下)
- Win8下加密文件使用(VHD + BitLocker)保证数据的安全
- Android安全讲座第八层[二] 替换已经安装后的应用的dex文件
- 加密文件中无法启用宏,安全选项对话框中无"启用此内容"选项
- 另类加密之用WinRAR打造安全加密文件
- android 中文件加密 解密 算法实战
- Android项目代码混淆(加密),添加混淆配置文件
- Android项目代码混淆(加密),添加混淆配置文件
- android开发之绝对安全(四) android开发中的加密方法
- 域环境下如何保护重要资料文件的安全(一)---EFS加密(上)
- 如何用gdb找到Android so文件中的加密key
- 如何用gdb找到Android so文件中的加密key
- 应用程序文件Android安全分析挑战:运行时篡改Dalvik字节码
- 域环境下如何保护重要资料文件的安全(一)---EFS加密(上) 推荐
- 最简单有效也是最适合程序员的代码文件安全加密保护方法——EFS
- Android 安全漏洞之文件系统
- Java/Android 加密解密压缩文件夹
- android加密文件在pc上破解的若干方法