AES和DES代码实现

DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。因为DES使用56位密钥,以现代计算能力,24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法。

AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。

package com.zyt;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.lang.reflect.Array;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;

/**
/**
 * @ClassName: Test_DES_AES 
 * @Model : (所属模块名称)
 * @Description: (这里用一句话描述这个类的作用) 
 * @author Administrator 
 * @date 2017年6月20日 下午3:02:45 
 */
public class Test_DES_AES {

    /**
    /**
     * main (这里用一句话描述这个方法的作用) 
     * @param args
     * void 
     * @ModifiedPerson Administrator
     * @date 2017年6月20日 下午3:02:45 
     */
    public static void main(String[] args) {
        //*****************************AES或DES加密 解密字符串*****************************
        //待加密内容  
        String str = "test";  
        //密码,长度要是8的倍数  
        String password = "12345678aa";  
        
        byte[] desEncryptResult = DESEncrypt(str.getBytes(), password);
        System.out.println("DES加密‘测试内容’的结果是:" + new String(desEncryptResult));
        
        byte[] desDecrypt = DESDecrypt(desEncryptResult, password);
        System.out.println("DES解密的结果是:" + new String(desDecrypt));
        

        byte[] aesEncrypt = AESEncrypt(str, password);
        System.out.println("AES加密‘测试内容’的结果是:" + new String(aesEncrypt));
        
        byte[] aesDecrypt = AESDecrypt(aesEncrypt, password);
        System.out.println("AES解密的结果是:" + new String(aesDecrypt));
        
        //String srcFilePath = "D:\\11.txt";//原文件
        String srcFilePath = "assets/11.txt";//原文件

        //***************************** DES加密 解密文件*****************************
        String encryptedFilePath = "assets/DES加密.txt";//加密后的文件
        String decryptedFilePath = "assets/DES解密.txt";//解密后的文件
        DESEncryptFile(srcFilePath, encryptedFilePath, password);
        DESDecryptFile(encryptedFilePath, decryptedFilePath, password);
        
        //***************************** AES加密 解密文件  *****************************
        String AESencryptedFilePath = "assets/AES加密.txt";//加密后的文件
        String AESdecryptedFilePath = "assets/AES解密.txt";//解密后的文件
        AESEncryptFile(srcFilePath, AESencryptedFilePath, password);
        AESDecryptFile(AESencryptedFilePath, AESdecryptedFilePath, password);
    }
    
    //  注意:DES加密和解密过程中,密钥password长度都必须是8的倍数
    public static byte[] DESEncrypt(byte[] datasource, String password){
        
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom secureRandom = new SecureRandom();
            // 从原始密匙数据创建DESKeySpec对象
            DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
            // 创建一个密匙工厂,
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
            //把DESKeySpec转换成一个SecretKey对象
            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            //用密匙初始化Cipher对象  
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, secureRandom);
                                   
            // 执行加密操作
            return cipher.doFinal(datasource);
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
    }
    
    //  注意:DES加密和解密过程中,密钥password长度都必须是8的倍数
    public static byte[] DESDecrypt(byte[] encrypted, String password){
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom secureRandom = new SecureRandom();
            // 创建一个DESKeySpec对象  
            DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
            // 创建一个密匙工厂  
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
            // 将DESKeySpec对象转换成SecretKey对象  
            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
            // Cipher对象实际完成解密操作  
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象  
            cipher.init(Cipher.DECRYPT_MODE, secretKey, secureRandom);
            // 真正开始解密操作  
            return cipher.doFinal(encrypted);
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        return null;
    }
    
  //DES解密文件
    public static void DESDecryptFile(String encryptedFilePath, String decryptedFilePath, String password) {
        try {
            
            // DES算法要求有一个可信任的随机数源
            SecureRandom secureRandom = new SecureRandom();
            // 从原始密匙数据创建DESKeySpec对象
            DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
            // 创建一个密匙工厂,
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
            //把DESKeySpec转换成一个SecretKey对象
            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            //用密匙初始化Cipher对象  
            cipher.init(Cipher.DECRYPT_MODE, secretKey, secureRandom);
            
            //将文件中的数据读入
            FileInputStream fis = new FileInputStream(encryptedFilePath);
            //输出解密数据到文件
            FileOutputStream fos = new FileOutputStream(decryptedFilePath);
            

            //方法一:
            /*CipherInputStream cis = new CipherInputStream(fis, cipher);
            byte[] b = new byte[1024];
            int i = 0;
            while( (i = cis.read(b)) != -1 ){
                fos.write(b, 0, i);
            }
            
            cis.close();
            */
            

            //方法二:
            byte[] bb = new byte[1024];
            int l = 0;
            while((l = fis.read(bb)) != -1){
                byte[] doFinal = cipher.doFinal(Arrays.copyOfRange(bb, 0, l));
                fos.write(doFinal, 0, doFinal.length);
            }
            
            fos.close();
            fis.close();

            System.out.println("DES解密文件结束");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        
    }

    //DES加密文件
    public static void DESEncryptFile(String srcFilePath, String desFilePath, String password) {
        try {
            
            // DES算法要求有一个可信任的随机数源
            SecureRandom secureRandom = new SecureRandom();
            // 从原始密匙数据创建DESKeySpec对象
            DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
            // 创建一个密匙工厂,
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
            //把DESKeySpec转换成一个SecretKey对象
            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            //用密匙初始化Cipher对象  
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, secureRandom);
            
            
            //将文件中的数据读入
            FileInputStream fis = new FileInputStream(srcFilePath);
            //输出加密数据到文件
            FileOutputStream fos = new FileOutputStream(desFilePath);
            
            //方法一:
            /*CipherInputStream cis = new CipherInputStream(fis, cipher);
            byte[] b = new byte[1024];
            int i = 0;
            while( (i = cis.read(b)) != -1 ){
                fos.write(b, 0, i);
            }
            cis.close();*/
            
            //方法二:
            byte[] bb = new byte[1024];
            int l = 0;
            while((l = fis.read(bb)) != -1){
                byte[] doFinal = cipher.doFinal(Arrays.copyOfRange(bb, 0, l));
                fos.write(doFinal, 0, doFinal.length);
            }
            
            fos.close();
            fis.close();

            System.out.println("DES加密文件结束");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        
    }
    
    public static byte[] AESEncrypt(String content, String password){
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] encoded = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
            //创建密码器
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            
            
            //真正的加密
            byte[] result = cipher.doFinal(content.getBytes("utf-8"));
            return result;
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
    }
    
    public static byte[] AESDecrypt(byte[] content, String password){
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] encoded = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
            //创建解密器
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            
            
            //真正的解密
            byte[] result = cipher.doFinal(content);
            
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
        
    }
    

    //AES加密文件
    public static void AESEncryptFile(String srcFilePath, String AESencryptedFilePath, String password) {
       
        try { SecureRandom secureRandom = new SecureRandom(password.getBytes());
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] encoded = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            
            
            //将文件中的数据读入
            FileInputStream fis = new FileInputStream(srcFilePath);
            //输出加密数据到文件
            FileOutputStream fos = new FileOutputStream(AESencryptedFilePath);
            CipherInputStream cis = new CipherInputStream(fis, cipher);
            byte[] b = new byte[1024];
            int i = 0;
            while( (i = cis.read(b)) != -1 ){
                fos.write(b, 0, i);
            }
            
            fos.close();
            cis.close();
            fis.close();

            System.out.println("AES加密文件结束");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }   


    //AES解密文件
    public static void AESDecryptFile(String AESencryptedFilePath, String AESdecryptedFilePath, String password) {
        try { SecureRandom secureRandom = new SecureRandom(password.getBytes());
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128, secureRandom);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] encoded = secretKey.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        
        
        //将文件中的数据读入
        FileInputStream fis = new FileInputStream(AESencryptedFilePath);
        //输出解密数据到文件
        FileOutputStream fos = new FileOutputStream(AESdecryptedFilePath);
        CipherInputStream cis = new CipherInputStream(fis, cipher);
        byte[] b = new byte[1024];
        int i = 0;
        while( (i = cis.read(b)) != -1 ){
            fos.write(b, 0, i);
        }
        
        fos.close();
        cis.close();
        fis.close();

        System.out.println("AES解密文件结束");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        
    }

}

复制代码

在Java项目中,上面的代码是完全能成功的,但在Android项目中,就会出现BadPaddingException: pad block corrupted in class SimpleCrypto in android,所以在Android中需要将秘钥固定SHA1PRNG,否则会因为秘钥不同而解密失败。

//AES加密文件
    public static void AESEncryptFile(InputStream is, String AESencryptedFilePath, String password) {
       
        try {
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
            secureRandom.setSeed(password.getBytes());
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] encoded = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            
            
            //输出加密数据到文件
            FileOutputStream fos = new FileOutputStream(AESencryptedFilePath);
            CipherInputStream cis = new CipherInputStream(is, cipher);
            byte[] b = new byte[1024];
            int i = 0;
            while( (i = cis.read(b)) != -1 ){
                fos.write(b, 0, i);
            }
            
            fos.close();
            cis.close();

            Log.i("?????", "AES加密文件结束");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }   


    //AES解密文件
    public static void AESDecryptFile(InputStream is, String AESdecryptedFilePath, String password) {
        try { 
            //在Android中需要将秘钥固定SHA1PRNG,否则会因为秘钥不同而解密失败(BadPaddingException: pad block corrupted in class SimpleCrypto in android)
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
            secureRandom.setSeed(password.getBytes());
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] encoded = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            
            //输出解密数据到文件
            FileOutputStream fos = new FileOutputStream(AESdecryptedFilePath);
            CipherInputStream cis = new CipherInputStream(is, cipher);
            byte[] b = new byte[1024];
            int i = 0;
            while( (i = cis.read(b)) != -1 ){
                fos.write(b, 0, i);
            }
            
            //方法二:
            /*byte[] bb = new byte[1024];
            int l = 0;
            while((l = is.read(bb)) != -1){
                byte[] doFinal = cipher.doFinal(Arrays.copyOfRange(bb, 0, l));
                fos.write(doFinal, 0, doFinal.length);
            }
            */
            fos.close();
            cis.close();
    
            System.out.println("AES解密文件结束");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        
    }
复制代码

#### YunSoul技术分享,扫码关注微信公众号##
  • ——只要你学会了之前所不会的东西,只要今天的你强过了昨天的你,那你就一直是在进阶的路上了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值