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

java 各加密算法示例(下)

作者: wyc0859 | 来源:发表于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