Java流编程实例之九--加密流

本例中的加密流使用了PBEWithMD5AndDES加密算法,该算法是对称加密算法,加密和解密使用的密钥是一样的。不同的是除了密码之外,还需要“盐”。代码如下:

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;

public class CypherStreamExam {
    public static void main(String[] args) {
        String infile = "D:\\a.txt";
        String outfile = "D:\\a.des";
        String password = "This is my key";
        byte[] salt = initSalt();
        encryptFile(infile, outfile, password, salt);

        infile = "D:\\a.des";
        outfile = "D:\\a.out";
        decryptFile(infile, outfile, password, salt);
    }

    //产生加密所用的盐
    public static byte[] initSalt() {
        //实例化安全随机数
        SecureRandom random = new SecureRandom();
        //产出盐
        return random.generateSeed(8);
    }

    private static void decryptFile(String infile, String outfile, String password, byte[] salt) {

        byte[] desKeyData = password.getBytes();
        try {
            FileInputStream fin = new FileInputStream(infile);
            FileOutputStream fout = new FileOutputStream(outfile);

            Provider sunJce = new com.sun.crypto.provider.SunJCE();
            Security.addProvider(sunJce);

            //创建密钥
            char[] pbeKeyData = password.toCharArray();
            PBEKeySpec pbeKeySpec = new PBEKeySpec(pbeKeyData);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
            PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);

            //解密
            Cipher pbe = Cipher.getInstance("PBEWithMD5AndDES");
            pbe.init(Cipher.DECRYPT_MODE, pbeKey, paramSpec);
            CipherOutputStream cout = new CipherOutputStream(fout, pbe);

            byte[] input = new byte[64];
            int len = 0;
            while ((len = fin.read(input)) != -1) {
                cout.write(input, 0, len);
            }
            cout.flush();
            cout.close();
            fin.close();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
    }

    private static void encryptFile(String filein, String fileout, String password, byte[] salt) {
        byte[] desKeyData = password.getBytes();
        try {
            FileInputStream fin = new FileInputStream(filein);
            FileOutputStream fout = new FileOutputStream(fileout);

            Provider sunJce = new com.sun.crypto.provider.SunJCE();
            Security.addProvider(sunJce);

            //创建密钥
            char[] pbeKeyData = password.toCharArray();
            PBEKeySpec pbeKeySpec = new PBEKeySpec(pbeKeyData);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
            PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);

            //加密
            Cipher pbe = Cipher.getInstance("PBEWithMD5AndDES");
            pbe.init(Cipher.ENCRYPT_MODE, pbeKey, paramSpec);
            CipherOutputStream cout = new CipherOutputStream(fout, pbe);

            byte[] input = new byte[64];
            int len = 0;
            while ((len = fin.read(input)) != -1) {
                cout.write(input, 0, len);
            }
            cout.flush();
            cout.close();
            fin.close();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
    }
}

在真实的应用中,加密方和解密方都知道密码,这个密码一般来说是双方约定的,例如你银行账户密码。如果这个密码被泄露,也不用担心,因为解密还需要“盐”。盐一般来说是由一种随机生成算法生成的,而且生存期很短。例如网上银行使用的U Key就是一种盐生成器,特别是“中国银行”的U Key,在进行转账时直接要求用户输入6位数字的盐。由于网上银行的服务端和客户手中的U Key使用同一种盐生成算法(这个算法当然是保密的,也无从泄露),因此保证了盐不会泄露,从而保证用户进行操作时不会泄密。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值