java对称加密算法

慕课网学习笔记
参考:Java加密算法



对称加密算法

加密密钥和解密密钥相同,加密运算和解密运算互为逆运算。是一种初等的加密算法。主要的算法有DES(3DES)、AES、PBE、IDEA。

对称加密算法 —— DES

数据加密标准(Data Encryption Standard),IBM提交的算法。
这里写图片描述

package des;

import java.security.Security;

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

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class JavaDES {

    private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串

    public static void main(String[] args) throws Exception {
        System.out.println("原始字符串:\n" + src);
        jdkDES();
        bouncyCastleDES();
    }

    /** jdk实现DES加密 */
    public static void jdkDES() throws Exception{

        //1.生成key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("des");//密钥生成器
        keyGenerator.init(56);//指定密钥长度为56位
        SecretKey secretKey = keyGenerator.generateKey();//用密钥生成器生成密钥
        byte[] byteKeys = secretKey.getEncoded();//得到密钥的byte数组

        //2.key转换
        DESKeySpec desKeySpec = new DESKeySpec(byteKeys);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("des");//秘密密钥工厂
        SecretKey convertSecretKey = factory.generateSecret(desKeySpec);

        //3.加密
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");//见上图的工作模式和填充模式
        cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);//加密模式
        byte[]result = cipher.doFinal(src.getBytes());

        System.out.println("jdk DES加密:\n" + Hex.encodeHexString(result));

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);//解密模式
        result = cipher.doFinal(result);
        System.out.println("jdk DES解密:\n" + new String(result));
    }

    /** Bouncy Castle实现DES加密 */
    public static void bouncyCastleDES() throws Exception{

        Security.addProvider(new BouncyCastleProvider());//增加provider

        //1.生成key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("des","BC");//密钥生成器,指定为bouncyCastle默认是sun的JCE
        keyGenerator.init(56);//指定key长度为56位
        keyGenerator.getProvider();
        SecretKey secretKey = keyGenerator.generateKey();//用密钥生成器生成密钥
        byte[] byteKeys = secretKey.getEncoded();//得到密钥的byte数组

        //2.key转换
        DESKeySpec desKeySpec = new DESKeySpec(byteKeys);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("des");//密钥工厂
        SecretKey convertSecretKey = factory.generateSecret(desKeySpec);

        //3.加密
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);//加密模式
        byte[]result = cipher.doFinal(src.getBytes());

        System.out.println("bc DES加密:\n" + Hex.encodeHexString(result));

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);//解密模式
        result = cipher.doFinal(result);
        System.out.println("bc DES解密:\n" + new String(result));
    }
}

运行结果:
这里写图片描述

在使用bc进行DES加解密的时候除了需要使用Security.addProvider()方法增加一个BouncyCastle,还需要指定密钥生成器的提供者为BC,如上面的代码的57行,否则会默认使用sun的JCE。应用场景:

这里写图片描述

对称加密算法——3重DES

3DES的好处是密钥长度增加。迭代次数增加。
这里写图片描述

实现的方式通常由JDK和BC两种,实现的方式和DES的实现方式大同小异:

package des;

import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Java3DES {

    private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串

    public static void main(String[] args) throws Exception {
        System.out.println("原始字符串:" + src + "\n");
        jdk3DES();
        bouncyCastle3DES();
    }

    /** jdk实现3DES */
    public static void jdk3DES() throws Exception{
        //1.生成key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("desede");//密钥生成器
//        keyGenerator.init(new SecureRandom()); //可以用它生成一个默认长度的key
        keyGenerator.init(168);//指定密钥长度为112位
        SecretKey secretKey = keyGenerator.generateKey();//用密钥生成器生成密钥
        byte[] byteKeys = secretKey.getEncoded();//得到密钥的byte数组

        //2.key转换
        DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(byteKeys);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("desede");//秘密密钥工厂
        SecretKey convertSecretKey = factory.generateSecret(deSedeKeySpec);

        //3.加密
        Cipher cipher = Cipher.getInstance("desede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);//加密模式
        byte[]result = cipher.doFinal(src.getBytes());

        System.out.println("jdk DES3加密:\n" + Hex.encodeHexString(result));

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);//解密模式
        result = cipher.doFinal(result);
        System.out.println("jdk DES3解密:\n" + new String(result) + "\n");
    }

    /** bc实现3DES */
    public static void bouncyCastle3DES() throws Exception{

        Security.addProvider(new BouncyCastleProvider());

        //1.生成key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("desede","BC");//密钥生成器[指定provider]
        keyGenerator.init(new SecureRandom());//指定密钥的长度为默认
        SecretKey secretKey = keyGenerator.generateKey();//用密钥生成器生成密钥
        byte[] byteKeys = secretKey.getEncoded();//得到密钥的byte数组

        //2.key转换
        DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(byteKeys);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("desede");//秘密密钥工厂
        SecretKey convertSecretKey = factory.generateSecret(deSedeKeySpec);

        //3.加密
        Cipher cipher = Cipher.getInstance("desede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);//加密模式
        byte[]result = cipher.doFinal(src.getBytes());

        System.out.println("bc DES3加密:\n" + Hex.encodeHexString(result));

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);//解密模式
        result = cipher.doFinal(result);
        System.out.println("bc DES3解密:\n" + new String(result) + "\n");

    }
}

运行结果:
这里写图片描述

对称加密算法——AES

AES产生的原因是3重DES的效率比较低而DES的安全性较低。AES是目前使用最多的对称加密算法,AES还有一个优势是至今尚未被破解。AES通常用于移动通信系统的加密以及基于SSH协议的软件(SSH Client、SecurityCRT)的加密。密钥长度以及实现方如下:
这里写图片描述

无政策限制权限文件是指:因为某些国家的进口管制限制,java发布的运行环境包中的一些加解密有一定的限制(因为美国政府的一些原因)。一般的JDK的jre的security包中的local_policy.jar和US_export_policy.jar都是没有内容的,所以只能使用128位加密。下面是JDK和BC实现的AES加密(步骤和DES类似):

package aes;

import java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class JavaAES {

    private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串

    public static void main(String[] args) throws Exception {
        System.out.println("初始字符串:" + src + "\n");
        jdkAES();
        bouncyCastleAES();
    }

    public static void jdkAES() throws Exception{

        //1.生成key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("aes");
        keyGenerator.init(128);//初始化key的长度,只能是128,
        SecretKey secretKey = keyGenerator.generateKey();//生成key
        byte[] keyBytes = secretKey.getEncoded();//得到key的字节数组

        //2.key的转换
        Key key = new SecretKeySpec(keyBytes, "aes");

        //3.加密
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//加解密方式+工作模式+填充方式
        cipher.init(Cipher.ENCRYPT_MODE, key);//以加密模式初始化
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("JDK AES加密:" + Base64.encodeBase64String(result));

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE, key);
        result = cipher.doFinal(result);
        System.out.println("JDK AES解密:" + new String(result));
    }

    public static void bouncyCastleAES() throws Exception{

        Security.addProvider(new BouncyCastleProvider());
        KeyGenerator keyGenerator = KeyGenerator.getInstance("aes", "BC");
        keyGenerator.init(128);//这里只能指定128,不能使用keyGenerator.init(new SecureRandom())
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] keyBytes = secretKey.getEncoded();

        Key key = new SecretKeySpec(keyBytes, "aes");

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("bc AES加密:" + Base64.encodeBase64String(result));

        cipher.init(Cipher.DECRYPT_MODE, key);
        result = cipher.doFinal(result);
        System.out.println("bc AES解密:" + new String(result));
    }
}

运行结果:
这里写图片描述

对称加密算法——PBE

PBE算法结合了消息摘要算法和对称加密算法的优点,是一种特殊的对称加密算法。Password Based Encryption,基于口令的加密。因为口令是比较好记的,就容易通过穷举、猜测的方式获得口令——针对这种情况,我们采用的方式是加盐(Salt),通过加入一些额外的内容(通常是随机字符)去扰乱。实现的方式有2种:JDK和BC。
这里写图片描述

这里写图片描述

JDK和BC实现的PBEWithMD5AndDES的算法如下:

package pbe;

import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class JavaPBE {

    private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串

    public static void main(String[] args) throws Exception {
        System.out.println("原始字符串:" + src);
        jdkPBE();
        bouncyCastlePBE();
    }

    public static void jdkPBE() throws Exception{

        //1.初始化盐
        SecureRandom secureRandom = new SecureRandom();//强加密随机数生成器
        byte[] salt= secureRandom.generateSeed(8);//产生盐必须是8位

        //2.口令与密钥
        String password = "root";
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());//密钥转换的对象
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");//实例化密钥转换工厂
        Key key = factory.generateSecret(pbeKeySpec);//由工厂产生key

        //3.加密
        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 100);//PBE输入参数的材料,盐,迭代100次
        Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
        cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("jdk PBE加密:" + Base64.encodeBase64String(result));

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
        result = cipher.doFinal(result);
        System.out.println("jdk PBE解密:" + new String(result));
    }

    public static void bouncyCastlePBE() throws Exception{

        Security.addProvider(new BouncyCastleProvider());//添加到provider

        SecureRandom secureRandom = new SecureRandom();
        byte[] salt = secureRandom.generateSeed(8);

        String password = "admin";
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES","BC");//指定provider
        Key key = factory.generateSecret(pbeKeySpec);

        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 50);
        Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
        cipher.init(Cipher.ENCRYPT_MODE, key,parameterSpec);
        byte[]result = cipher.doFinal(src.getBytes());

        System.out.println("bc PBE加密:" + Base64.encodeBase64String(result));

        cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
        result = cipher.doFinal(result);
        System.out.println("bc PBE解密:" + new String(result));
    }
}

应用场景:
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值