JAVA加密算法- 对称加密算法二

对称加密算法概念

  • 加密密钥和解密密钥相同,大部分算法加密揭秘过程互逆。

  • 特点:算法公开、(相比非对称加密)计算量小、加密速度快、效率高。

  • 弱点:双方都使用同样的密钥,安全性得不到保证。

常用对称加密算法

  • DES(Data Encryption Standard)

  • 3DES(DES加强版,使用3次DES计算,Triple DES,DESede)

  • AES(Advanced Encryption Standard,3DES加强版)

JDK版DES/3DES/AES算法调用模板

1. 生成密钥

//KeyGenerator,密钥生成器
KeyGenerator keyGen = KeyGenerator.getInstance("DES");//算法:DES,DESede,AES

//初始化密钥生成器
keyGen.init(56); //各算法密钥长度不同,参见说明

//生成密钥
SecretKey secretKey = keyGen.generateKey();

//生产字节码数据
byte[] key = secretKey.getEncoded();

说明:
1.通过「KeyGenerator.getInstance("DES")」生成密钥,
2.参数为算法名称:分别对应DES、DESede(即3DES)、AES
3.每种算法密钥长度参数:DES(56),3DES(112,168),AES(192,256)

2.加/解密

//通过字节码数据key 恢复密钥
SecretKey secretKey = new SecretKeySpec(key, "DES");

//Cipher完成加密/解密工作
Cipher cipher = Cipher.getInstance("DES");

//根据密钥,对Cipher初始化,并选择加密还是解密
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

byte[] result = cipher.doFinal(data);

1.加密或解密都通过cipher.init()设置,参数:ENCRYPT_MODE/DECRYPT_MODE2.加密或解密都通过cipher.doFinal() 执行,获得byte[]类型结果。

代码示例

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


public class DESUtil {
    
    /*
     * 生成密钥
     */
    public static byte[] initKey() throws Exception{
        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
        keyGen.init(56);
        SecretKey secretKey = keyGen.generateKey();
        return secretKey.getEncoded();
    }

    
    /*
     * DES 加密
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception{
        SecretKey secretKey = new SecretKeySpec(key, "DES");
        
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherBytes = cipher.doFinal(data);
        return cipherBytes;
    }
    
    
    /*
     * DES 解密
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception{
        SecretKey secretKey = new SecretKeySpec(key, "DES");
        
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] plainBytes = cipher.doFinal(data);
        return plainBytes;
    }

    //Test
    public static void main(String[] args) throws Exception {
    byte[] desKey = DESUtil.initKey();
        System.out.println("DES KEY : " + BytesToHex.fromBytesToHex(desKey));
        byte[] desResult = DESUtil.encrypt(DATA.getBytes(), desKey);
        System.out.println(DATA + ">>>DES 加密结果>>>" + BytesToHex.fromBytesToHex(desResult));
        
        byte[] desPlain = DESUtil.decrypt(desResult, desKey);
        System.out.println(DATA + ">>>DES 解密结果>>>" + new String(desPlain));
    }
}

JAVA加密算法- 非对称加密算法(DH,RSA)

非对称密码概念

发送者使用接收者的公钥加密,接收者使用自己的私钥解密。

需要两个密钥进行加密或解密,分为公钥和私钥

特点:安全性高,速度慢

常用算法

  • DH密钥交换算法

  • RSA算法

  • ElGamal算法那

用途

  • 密钥交换(DH)

双方在没有确定共同密钥的情况下,生成密钥,不提供加密工作,加解密还需要其他对称加密算法实现

  • 加密/解密(RSA)

  • 数字签名(RSA)

DH算法示例

import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

//1 生成源密钥
//2 把源公钥交给目标,目标通过源公钥,生成目标公钥和私钥
//3 把目标公钥交给源
//4 双方使用对方的公钥和和自己的私钥,生成本地密钥
//5 如果双方生成本地密钥相同则完成密钥交换
public class DHUtil {

    public static final String PUBLIC_KEY = "DH_Public_Key";
    public static final String PRIVATE_KEY = "DH_Private_key";

    /**
     * 生成源密钥对
     * @return
     * @throws Exception
     */
    public static Map<String,Object> initSourceKey() throws Exception{
        //创建KeyPairGenerator的实例,选用DH算法
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");

        //初始化密钥长度,默认1024,可选范围512-65536 & 64的倍数
        keyPairGenerator.initialize(1024);

        //生成密钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
        DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();

        //将密钥对放入Map
        Map<String,Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, dhPublicKey);
        keyMap.put(PRIVATE_KEY, dhPrivateKey);
        return keyMap;
    }

    /**
     * 通过源公钥 生成 目标密钥对
     * @param sourcePublicKey
     * @return
     * @throws Exception
     */
    public static Map<String,Object> initTargetKey(byte[] sourcePublicKey) throws Exception {

        KeyFactory keyFactory = KeyFactory.getInstance("DH");

        //通过源公钥,生成keySpec,使用KeyFactory生成源PublicKey相关信息
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(sourcePublicKey);
        DHPublicKey sourcePublic = (DHPublicKey) keyFactory.generatePublic(keySpec);

        DHParameterSpec dhPublicKeyParams = sourcePublic.getParams();

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
        keyPairGenerator.initialize(dhPublicKeyParams);

        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
        DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();

        //将密钥对放入Map
        Map<String,Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, dhPublicKey);
        keyMap.put(PRIVATE_KEY, dhPrivateKey);
        return keyMap;
    }

    /**
     * 使用一方的公钥和另一方的私钥,生成本地密钥
     * @return
     */
    public static byte[] generateLocalSecretKey(byte[] aPublicKey, byte[] bPrivateKey) throws Exception{
        KeyFactory keyFactory = KeyFactory.getInstance("DH");

        //通过A公钥,生成keySpec,使用KeyFactory生成A PublicKey相关信息
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        //通过B私钥,生成B PrivateKey相关信息
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //通过KeyAgreement对A的PublicKey和B的PrivateKey进行加密
        KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
        keyAgreement.init(privateKey);
        keyAgreement.doPhase(publicKey,true);


        return keyAgreement.generateSecret("AES").getEncoded();//算法使用对称加密算法(DES,DESede,AES)
        //return keyAgreement.generateSecret();                // 也可以不选择算法,使用默认方法计算
    }

    //获取公钥字节数组
    public static byte[] getPublicKey(Map<String,Object> map){
        return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded();
    }

    //获取私钥字节数组
    public static byte[] getPrivateKey(Map<String,Object> map){
        return ((DHPrivateKey) map.get(PRIVATE_KEY)).getEncoded();
    }

    public static void main(String[] args) throws Exception {

        byte[] source_public_key;
        byte[] source_private_key;
        byte[] source_local_key;

        byte[] target_public_key;
        byte[] target_private_key;
        byte[] target_local_key;

        Map<String, Object> sourceKey = initSourceKey();
        source_public_key = getPublicKey(sourceKey);
        source_private_key = getPrivateKey(sourceKey);

        System.out.println("源公钥:"+BytesToHex.fromBytesToHex(source_public_key));
        System.out.println("源私钥:"+BytesToHex.fromBytesToHex(source_private_key));

        Map<String, Object> targetKey = initTargetKey(getPublicKey(sourceKey));
        target_public_key = getPublicKey(targetKey);
        target_private_key = getPrivateKey(targetKey);

        System.out.println("目标公钥:"+BytesToHex.fromBytesToHex(target_public_key));
        System.out.println("目标私钥:"+BytesToHex.fromBytesToHex(target_private_key));

        source_local_key = generateLocalSecretKey(target_public_key, source_private_key);
        target_local_key = generateLocalSecretKey(source_public_key, target_private_key);

        System.out.println("源本地密钥:"+BytesToHex.fromBytesToHex(source_local_key));
        System.out.println("目标本地密钥:"+BytesToHex.fromBytesToHex(target_local_key));
    }
}

RSA 加密/解密 示例

公钥加密,私钥解密

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * RSA加密工具
 */
public class RSAUtil {

    public static final String PUBLIC_KEY = "RSA_Public_Key";
    public static final String PRIVATE_KEY = "RSA_Private_Key";

    /**
     * 初始化密钥
     * @return
     * @throws Exception
     */
    public static Map<String,Object> initKey() throws Exception{
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);//512-65536 & 64的倍数
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String,Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    public static RSAPublicKey getPublicKey(Map<String,Object> keyMap) {
        return (RSAPublicKey) keyMap.get(PUBLIC_KEY);
    }

    public static RSAPrivateKey getPrivateKey(Map<String,Object> keyMap){
        return (RSAPrivateKey) keyMap.get(PRIVATE_KEY);
    }

    /**
     * 使用公钥对数据进行加密
     * @param data
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 使用私钥解密
     * @param data
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        String data = "周杰伦-东风破";
        Map<String, Object> keyMap = initKey();

        byte[] miwen = encrypt(data.getBytes(),getPublicKey(keyMap));
        System.out.println("加密后的内容:"+BytesToHex.fromBytesToHex(miwen));

        byte[] plain = decrypt(miwen, getPrivateKey(keyMap));
        System.out.println("解密后的内容:"+new String(plain));

    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值