美文网首页
java 各加密算法示例(下)

java 各加密算法示例(下)

作者: SKING_a4d9 | 来源:发表于2021-05-04 01:08 被阅读0次

对称加密算法(JDK和BC实现方式)

DES (是数据加密标准,很多年前常用,已被破解不具备安全性)
3DES(三重DES,又称:Triple DES或DESede)
AES (是目前最常用的方式;因为3DES速度较慢;AES通常用于移动通信系统加密以及基于SSH协议的软件)
PBE (基于口令的加密,未举例)

非对称加密算法(JDK和BC实现方式)

公钥+密钥
DH(密钥交换算法)
RSA(基于因子分解,最常用)
ELGamal (椭圆曲线加密,未举例)
如何安全的传递密钥,是对称加密算法的困扰;但非对称加密算法就很好的解决了这个问题

数字证书

用于验证,而不是用于解密


3DES

JDK和BC 的3DES 是非常相似的
JDK和BC 的DES 也是非常相似的,把DESede改成DES就是DES算法了

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.Test;
import javax.crypto.*;
import javax.crypto.spec.DESedeKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;

public class options2 {
    private static String src = "ruhuashop.com";

    @Test
    public void index() {
        jdk3DES();
        bc3DES();
    }

    private static void jdk3DES() {
        try {
            //生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
            keyGenerator.init(168);
            keyGenerator.init(new SecureRandom());
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] bytesKey = secretKey.getEncoded();
            //KEY转换
            DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
            Key convertSecretKey = factory.generateSecret(desKeySpec);
            //加密
            Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
            byte[] result = cipher.doFinal(src.getBytes());
            System.out.println("jdk 3des encrypt : " +Hex.encodeHexString(result));
            //解密
            cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
            result = cipher.doFinal(result);
            System.out.println("jdk 3des decrypt : " +new String(result));
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void bc3DES() {
        try {
            Security.addProvider(new BouncyCastleProvider());
            //生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede","BC");
            keyGenerator.getProvider();
            keyGenerator.init(168);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] bytesKey = secretKey.getEncoded();
            //KEY转换
            DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
            Key convertSecretKey = factory.generateSecret(desKeySpec);

            //加密
            Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
            byte[] result = cipher.doFinal(src.getBytes());
            System.out.println("jdk 3des encrypt : " + Hex.encodeHexString(result));
            //解密
            cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
            result = cipher.doFinal(result);
            System.out.println("jdk 3des decrypt : " +new String(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

AES

BC方式的AES和JDK很相似,所以以上只举例一种

 public static void jdkAES() {
        try {
            //生成KEY
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] keyBytes = secretKey.getEncoded();
            //key转换
            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("jdk aes encrypt : " + Base64.encodeBase64String(result));
            //解密
            cipher.init(Cipher.DECRYPT_MODE, key);result = cipher.doFinal(result);
            System.out.println("jdk aes desrypt : " + new String(result));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

DH

public static void jdkDH() {
        try {
            // 初始化发送方密钥
            KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            senderKeyPairGenerator.initialize(512);
            KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
            byte[] senderPublicKey = senderKeyPair.getPublic().getEncoded();

            // 初始化接收方的密钥
            KeyFactory instance = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKey);
            PublicKey sendPublicKeyTemp = instance.generatePublic(x509EncodedKeySpec);
            DHParameterSpec dhParameterSpec = ((DHPublicKey) sendPublicKeyTemp).getParams();
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
            keyPairGenerator.initialize(dhParameterSpec);
            // 接收方生成密钥
            KeyPair generateKeyPair = keyPairGenerator.generateKeyPair();
            byte[] receiverPublicKey = generateKeyPair.getPublic().getEncoded();
            PrivateKey receiverPrivateKey = generateKeyPair.getPrivate();

            // 接收方密钥构建
            KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
            receiverKeyAgreement.init(receiverPrivateKey);
            receiverKeyAgreement.doPhase(senderKeyPair.getPublic(), true);

            // 使用我的密钥和你的公钥生成密钥
            SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");
            System.out.println("receiverDesKey:"+receiverDesKey);

            // 发送方密钥构建
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(receiverPublicKey);
            PublicKey receiverPublicKeyTemp = keyFactory.generatePublic(x509EncodedKeySpec2);

            // 发送方拿到接收方返回的公钥做本地密钥
            KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
            senderKeyAgreement.init(senderKeyPair.getPrivate());
            senderKeyAgreement.doPhase(receiverPublicKeyTemp, true);

            // 使用你的密钥我的公钥进行构建           
            SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");
            System.out.println("senderDesKey:" + senderDesKey);

            // 判断双方的本地密钥是否相同
            if (Objects.equals(receiverDesKey, senderDesKey)) {
                System.out.println("双方密钥相同");
            }

            // 加密
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
            byte[] result = cipher.doFinal(src.getBytes());
            System.out.println("加密结果为 : " + Hex.encodeHexString(result));

            // 解密
            cipher.init(Cipher.DECRYPT_MODE, senderDesKey);
            result = cipher.doFinal(result);
            System.out.println("解密结果为 : " + new String(result));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

由于JDK8 update 161之后,DH的密钥长度至少为512位,但AES算法密钥不能达到这样的长度,长度不一致所以导致报错。
解决的方法:将 -Djdk.crypto.KeyAgreement.legacyKDF=true 写入JVM系统变量中



RSA算法

  • 唯一广泛接受并实现
  • 数据加密&数字签名
  • 公钥加密、私钥解密
  • 私钥加密、公钥解密
public static void jdkRSA() {
        try {
            // 构建密钥对儿
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            System.out.println("Public Key : " + org.apache.commons.codec.binary.Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            System.out.println("Private Key : " + org.apache.commons.codec.binary.Base64.encodeBase64String(rsaPrivateKey.getEncoded()));

            // 2.私钥加密,公钥解密---加密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] result = cipher.doFinal(src.getBytes());
            System.out.println("私钥加密,公钥解密------加密 : " + Base64.encodeBase64String(result));

            // 3.私钥加密,公钥解密---解密
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            result = cipher.doFinal(result);
            System.out.println("私钥加密,公钥解密------解密 : " + new String(result));

            // 4.公钥加密,私钥解密---加密
            x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            result = cipher.doFinal(src.getBytes());

            System.out.println("公钥加密,私钥解密------加密 : " + Base64.encodeBase64String(result));

            // 5.公钥加密,私钥解密---解密
            pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            result = cipher.doFinal(result);
            System.out.println("公钥加密,私钥解密------解密 : " + new String(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

数字签名 —— 带有密钥(公钥、私钥)的消息摘要算法

私钥签名、公钥验证

public static void jdkRSASign() {
       try {
           //1.初始化密钥
           KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
           keyPairGenerator.initialize(512);
           KeyPair keyPair = keyPairGenerator.generateKeyPair();
           RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();  //公钥验证
           RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate(); //私钥签名

           //2.执行签名
           PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
           KeyFactory keyFactory = KeyFactory.getInstance("RSA");
           PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
           Signature signature = Signature.getInstance("MD5withRSA");
           signature.initSign(privateKey);
           signature.update(src.getBytes());
           byte[] result = signature.sign();
           System.out.println("jdk rsa sign : " + Hex.encodeHexString(result));

           //3.验证签名
           X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
           keyFactory = KeyFactory.getInstance("RSA");
           PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
           signature = Signature.getInstance("MD5withRSA");
           signature.initVerify(publicKey);
           signature.update(src.getBytes());
           boolean bool = signature.verify(result);
           System.out.println("jdk rsa verify : " + bool);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

相关文章

网友评论

      本文标题:java 各加密算法示例(下)

      本文链接:https://www.haomeiwen.com/subject/objqdltx.html