JAVA安全知识

Java安全知识汇总:对称加密

引用转载请注明出处,Thanks!

  • BASE64加密
  • DES加密
一、BASE64加密

简介:Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。[2]

  1. 使用BASE64加密

使用BASE64Encoder类的encodeBuffer()方法,产生一个String类型的返回值,即可得加密后的字符。

import sun.misc.BASE64Encoder;

public class BASE64Test {

    public static void main(String[] args) {
        String data = "csdn博客";
        System.out.println("加密前:"+ data);

        BASE64Encoder be = new BASE64Encoder();
        String data2 = be.encodeBuffer(data.getBytes());

        System.out.println("加密后:"+ data2);
    }
}

输出:

加密前:csdn博客
加密后:Y3NkbrKpv80=

备注:使用BASE64加密后的字符串个数都是4的倍数,一个字符占两个字节,也就是说BASE64加密以后的字符串必须是8个字节的倍数,如果不足,需要在后面补上”=”。[1]

  1. 使用BASE64解密
import java.io.IOException;
import sun.misc.BASE64Decoder;

public class BASE64Test2 {

    public static void main(String[] args) {
        String data = "Y3NkbrKpv80=";
        System.out.println("加密字符:"+ data);

        BASE64Decoder bd = new BASE64Decoder();
        byte[] data2 = null;
        try {
            data2 = bd.decodeBuffer(data);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("加密后:"+ new String(data2));
    }
}

输出:

加密字符:Y3NkbrKpv80=
加密后:csdn博客
二、DES加密

简介:DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。[3]
DES加密需要先生成一个密钥,加密端通过该密钥进行加密,解密时,解密的一端也需要使用该密钥对数据解密,密钥生成以后是byte[]类型的数据,这种加密手段也称为对称加密。

  1. 生成DES的密钥
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class DESTest {

    public static void main(String[] args) {
        DESTest dt = new DESTest();
        dt.initKey();
    }

    /**
     * 生成DES密钥,并保存到文件中
     */
    public void initKey(){
        //产生一个随机数源
        SecureRandom secureRandom = new SecureRandom();
        //为DES算法生成一个KeyGenerator
        KeyGenerator generator;
        try {
            generator = KeyGenerator.getInstance("DES");
            generator.init(secureRandom);
            SecretKey key = generator.generateKey();
            //生成密钥数据保存到文件中
            writeFile(key.getEncoded(), "KeyData.dat");
            System.out.println("密钥生成完成,存放在项目根目录中");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将生成的byte[] 数据存到文件中
     * @param data DES生成的密钥
     * @param fileName 存放文件名
     */
    public void writeFile(byte[] data,String fileName){
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(fileName);
            fileOutputStream.write(data);
            fileOutputStream.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 使用DES加密
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class DESTest2 {

    /**
     * 读取存放的DES密钥文件并返回byte[]
     * @param fileName
     * @return byte[]
     */
    public byte[] readFile(String fileName){
        try {
            //创建文件
            File file = new File(fileName);
            //创建文件输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] data = new byte[(int)file.length()];
            fileInputStream.read(data);
            fileInputStream.close();
            return data;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch(IOException e2){
            e2.printStackTrace();
        }
        return null;
    }

    /**
     * 使用DESKeySpec和SecretKeyFactory类把密钥数据转换为密钥对象
     * @return DES Key
     */
    public Key toKey(){
        try {
            byte[] key = readFile("keyData.dat");
            DESKeySpec keySpec = new DESKeySpec(key);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
            //转化密钥成key进行加密解密
            SecretKey secretKey = factory.generateSecret(keySpec);
            return secretKey;
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e){
            e.printStackTrace();
        } catch (InvalidKeySpecException e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 加密
     * @param data
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public void encrypt(byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
        Key key = toKey();
        //使用Cipher实际完成加密操作
        Cipher cipher = Cipher.getInstance("DES");
        //使用密钥初始化Cipher
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] f = cipher.doFinal(data);
        //调用writeFile,存下加密后的文件
        DESTest dt = new DESTest();
        dt.writeFile(f, "fileData.dat");
    }

    public static void main(String[] args) {
        try {

            DESTest2 dt2 = new DESTest2();          
            String data = "csdn博客";
            //调用encrypt进行加密
            dt2.encrypt(data.getBytes());

        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
    }
}
  1. 使用DES解密

首先清楚,密钥保存在项目根目录的keyData.dat中,加密后的文件保存在fileData.data中。

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class DESTest3 {
    /**
     * 解密
     * @return
     */
    public String decrypt(){
        //获得保存的密钥
        DESTest2 dt2 = new DESTest2();
        Key key = dt2.toKey();
        try {
            Cipher cipher = Cipher.getInstance("DES");
            //初始化
            cipher.init(Cipher.DECRYPT_MODE, key);
            //读取到加密后的文件
            byte[] f = dt2.readFile("fileData.dat");
            //解密
            byte[] f2 = cipher.doFinal(f);
            return new String(f2);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        DESTest3 dt3 = new DESTest3();
        String data = dt3.decrypt();
        System.out.println("解密后的数据是:"+ data);
    }
}

结果为:解密后的数据是:csdn博客

引用:

[注释1]:JAVA开发实战1200例(第二卷)
[注释2]:百度百科:https://baike.baidu.com/item/base64/8545775?fr=aladdin
[注释3]:百度百科:https://baike.baidu.com/item/DES/210508?fr=aladdin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值