我们知道采用DES加密算法的文件,有可能会被人相对容易破解掉,并不是很安全,如果采用多次混合加密方式那么就会增加被破解难度。
* 3DES即三重DES加密算法,也被称为DESede或者Triple DES。使用三(或两)个不同的密钥对数据块进行三次(或两次)DES加密(加密一次要比进行普通加密的三次要快)。
* 三重DES的强度大约和112-bit的密钥强度相当。通过迭代次数的提高了安全性,但同时也造成了加密效率低的问题。
3DES属于对称加密
*密钥长度:112位/168位
*工作模式: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,下面是详细使用方法:
public class DES3Model { public static final String KEY_ALGORITHM = "DESede"; private static final String DEFAULT_CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding"; // private static final String DEFAULT_CIPHER_ALGORITHM = "DESede/ECB/ISO10126Padding"; private String srcFile="",destionFile=""; /** * 初始化密钥 * * @return byte[] 密钥 * @throws Exception */ public byte[] initSecretKey() throws Exception{ //密钥的 KeyGenerator 对象 KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM); //指定密钥大小 kg.init(168); //生成一个密钥 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 Key 密钥 * @throws Exception */ private static Key toKey(byte[] key) throws Exception{ //实例化DES密钥规则 DESedeKeySpec dks = new DESedeKeySpec(key); //实例化密钥工厂 SecretKeyFactory skf = SecretKeyFactory.getInstance(KEY_ALGORITHM); //生成密钥 SecretKey secretKey = skf.generateSecret(dks); return secretKey; } /** * 加密 * * @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); } 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()); cipher.init(Cipher.ENCRYPT_MODE, sessionKey); 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()); cipher.init(Cipher.DECRYPT_MODE,sessionKey); 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(); } /** * 解密 * * @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); } }
加密文件:
String srcPath="/mnt/sdcard/a.txt",srcjiamiFile,outjiemiFile; void test3desJiaMi(){ 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+"des3_jiAMi"+suffix; DES3Model model_des3=new DES3Model(); model_des3.setSrcFile(srcPath); model_des3.setDestionFile(srcjiamiFile); try { key_des3=new SecretKeySpec(model_des3.initSecretKey(), DES3Model.KEY_ALGORITHM); model_des3.encryptionFile(key_des3); } catch (Exception e) { e.printStackTrace(); } } }
解密文件:
String srcjiamiFile="/mnt/sdcard/ades3_jiAMi.txt",outjiemiFile; void test3desJieMi(){ f=new File(srcjiamiFile); 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+"des3_jieMi"+suffix; DES3Model model_des3=new DES3Model(); model_des3.setSrcFile(srcjiamiFile); model_des3.setDestionFile(outjiemiFile); try { model_des3.descryptionFile(key_des3); } catch (Exception e) { e.printStackTrace(); } } }