1.安全传输加密算法

一.何为安全传输?

安全传输就是,即使人家从网络监听到我们发送的数据包,也无法破译我们的信息,或者破译的机会十分渺茫。
那么这是如何实现的呢? 毕竟,我们想要传输加密信息,接收者解密的话则需要密钥,而密钥也是需要通过网络传输的啊!!

1.非对称加密

密钥的安全传输需要用到一种特殊的加密技术: 非对称加密。

1.1 何为非对称加密?

一次非对称加密信息传输包含三个要素: 公钥,私钥,传输报文

  • 公钥: 源服务器生成,通过网络传输到目标服务器
  • 私钥: 源服务器生成,绝对保存在本地,不经过任何传输到任何地方,只存在源服务器本地。
  • 传输报文: 通过公钥或私钥进行加解密
    非对称加密运行流程如下:
    首先,源服务器生成一对密钥: 公钥,私钥。 公钥通过网络明文发送给目标服务器,然后源服务器将要发送的报文用私钥加密后发送给目标服务器,目标服务器拿到密文用公钥解密(这个过程不安全,因为如果其他人监听到公钥了,那么他就可以用公钥对源服务器发出的报文进行解密) ,接着目标服务器用公钥对要发送的报文进行加密,发送到源服务器,源服务器用私钥进行解密即可(这个过程是安全的,因为私钥只有源服务器拥有)

1.2 非对称加密算法RSA实例

典型的非对称加密算法RSA应用实例:

package RSA;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;

public class RSADemo {

    private static final String ENCODE = "UTF-8";

    private static final String AES = "AES";
    
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";


    /**
     * AES加密
     * @param content 加密内容
     * @param AES_IV 加密偏移量
     * @param AES_KEY 加密密钥
     * @return 密文
     * @throws Exception 加密过程中出现的异常
     */
    public static String AESEncryptEncode(String content,String AES_IV,String AES_KEY) throws Exception{
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(AES_KEY);
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte,AES);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,new IvParameterSpec(decoder.decode(AES_IV)));

        byte[] result = cipher.doFinal(content.getBytes(ENCODE));

        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * AES解密
     * @param content 密文
     * @param AES_IV 解密偏移量
     * @param AES_KEY 解密密钥
     * @return 解密后明文
     * @throws Exception 异常
     */
    public static String AESDecodeDecrypt(String content,String AES_IV,String AES_KEY) throws Exception{

        Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(AES_KEY);
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte,AES);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(decoder.decode(AES_IV)));

        byte[] base64 = decoder.decode(content);

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

        return new String(result, Charset.forName(ENCODE));
    }

    /**
     * Rsa生成公钥,密钥
     * @return 返回公钥,密钥字符串数组 0--密钥 1--公钥
     * @throws NoSuchAlgorithmException 异常信息
     */
    public static String[] RsaGenera() throws NoSuchAlgorithmException {
        // 1.初始化发送方密钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(512);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String[] results = new String[2];
        results[0] = Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded());
        results[1] = Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded());
        return results;
    }

    /**
     * Rsa私钥加密
     * @param privateKey 私钥
     * @param content 明文
     * @return 返回密文
     * @throws Exception 异常
     */
    public static String RsaPrivateEncrypt(String privateKey,String content) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey1);
        byte[] result = cipher.doFinal(content.getBytes(ENCODE));
        //System.out.println("私钥加密、公钥解密 ---- 加密:" + Arrays.toString(result));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * Rsa公钥解密
     * @param publicKey 公钥
     * @param content 密文
     * @return 明文
     * @throws Exception 异常
     */
    public static String RsaPublicUnEncrypt(String publicKey,String content) throws Exception{
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey1 = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey1);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
        //System.out.println("私钥加密、公钥解密 ---- 解密:" + Base64.getEncoder().encodeToString(result));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * Rsa公钥加密
     * @param publicKey 公钥
     * @param content 明文
     * @return 密文
     * @throws Exception 异常
     */
    public static String RsaPublicEncrypt(String publicKey,String content) throws Exception{
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey1 = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey1);
        byte[] result = cipher.doFinal(content.getBytes(ENCODE));
        //System.out.println("公钥加密、私钥解密 ---- 加密: "+Base64.getEncoder().encodeToString(result2));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * Rsa私钥解密
     * @param privateKey 私钥
     * @param content 密文
     * @return 解密后明文
     * @throws Exception 异常
     */
    public static String RsaPrivateUnEncrypt(String privateKey,String content) throws Exception{
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey1);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
        //System.out.println("公钥加密、私钥解密 ---- 解密:" + new String(result));
        return new String(result);
    }

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

        String[] keys = RsaGenera();
        System.out.println("RSA生成密钥对:");
        System.out.println("公钥:"+keys[1]);
        System.out.println("私钥:"+keys[0]);
        
        String test = RsaPublicEncrypt(keys[1],"今天打老虎");
        System.out.println("公钥加密:今天打老虎-->"+test);

        String test2 = RsaPrivateUnEncrypt(keys[0],test);
        System.out.println("私钥解密:"+test+"-->"+test2);

    }

}

运行结果:
在这里插入图片描述

2.对称加密

对称加密技术是一种很广泛的加密技术。

2.1 何为对称加密

对称加密的元素主要有两个: 密钥,报文

  • 密钥: 通信双方提前约定好的密钥
  • 报文: 用相同的密钥进行加密和解密的报文

对称加密的运行流程如下:
首先通信双方约定好密钥,然后源服务器发送到目标服务器的密文用密钥加密,目标服务器用密钥解密密文即可。(如果密钥还是通过网络传输,则这种通信还是不安全的,除非双方线下约定且保证没有第三个人知道)

2.2 对称加密AES/CBC加密实例

package RSA;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Base64;

public class AESDemo {

    private static final String ENCODE = "UTF-8";

    private static final String AES = "AES";

    private static final String AES_IV = "49U2GlzcrBmS9UVz+mEE3Q==";

    private static final String AES_KEY = "D8M1+eb6mzq0Oc23K+YQYQ==";

    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";


    /**
     * AES加密
     * @param content 加密内容
     * @param AES_IV 加密偏移量
     * @param AES_KEY 加密密钥
     * @return 密文
     * @throws Exception 加密过程中出现的异常
     */
    public static String AESEncryptEncode(String content,String AES_IV,String AES_KEY) throws Exception{
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(AES_KEY);
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte,AES);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,new IvParameterSpec(decoder.decode(AES_IV)));

        byte[] result = cipher.doFinal(content.getBytes(ENCODE));

        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * AES解密
     * @param content 密文
     * @param AES_IV 解密偏移量
     * @param AES_KEY 解密密钥
     * @return 解密后明文
     * @throws Exception 异常
     */
    public static String AESDecodeDecrypt(String content,String AES_IV,String AES_KEY) throws Exception{

        Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(AES_KEY);
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte,AES);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(decoder.decode(AES_IV)));

        byte[] base64 = decoder.decode(content);

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

        return new String(result, Charset.forName(ENCODE));
    }



    public static void main(String[] args) throws Exception {
        String m = AESEncryptEncode("今天打老虎",AES_IV,AES_KEY);
        System.out.println("AES对称加密: "+m);
        System.out.println("AES对称解密:"+AESDecodeDecrypt(m,AES_IV,AES_KEY));
    }

}

运行结果:
在这里插入图片描述

3. 通过非对称+对称加密实现网络安全传输

通过前面的学习我们知道,安全传输的关键在于密钥不能被泄露,我们可以试想一下,我们能不能先用非对称加密传输密钥,然后用对称加密进行报文传输,这样的话不久实现了,加密传输。

流程如下:
首先源服务器生成私钥,公钥,将公钥发送给目标服务器,然后目标服务器用公钥加密对称密钥发送给源服务器,接着源服务器将密文解密得到对称密钥,这样就只有双方知道对称密钥了,不存在第三方知道了。
然后以后的信息传输就用对称密钥加解密即可。

3.1 结合RSA和AES/CBC实现安全传输Demo

非对称加密进行对称密钥传输,对称加密实现报文安全传输。

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;

public class EncryptUtil {

    private static final String ENCODE = "UTF-8";

    private static final String AES = "AES";

    private static final String AES_IV = "49U2GlzcrBmS9UVz+mEE3Q==";

    private static final String AES_KEY = "D8M1+eb6mzq0Oc23K+YQYQ==";

    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";


    /**
     * AES加密
     * @param content 加密内容
     * @param AES_IV 加密偏移量
     * @param AES_KEY 加密密钥
     * @return 密文
     * @throws Exception 加密过程中出现的异常
     */
    public static String AESEncryptEncode(String content,String AES_IV,String AES_KEY) throws Exception{
       Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(AES_KEY);
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte,AES);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,new IvParameterSpec(decoder.decode(AES_IV)));

        byte[] result = cipher.doFinal(content.getBytes(ENCODE));

        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * AES解密
     * @param content 密文
     * @param AES_IV 解密偏移量
     * @param AES_KEY 解密密钥
     * @return 解密后明文
     * @throws Exception 异常
     */
    public static String AESDecodeDecrypt(String content,String AES_IV,String AES_KEY) throws Exception{

       Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyByte = decoder.decode(AES_KEY);
        int base = 16;
        if (keyByte.length % base != 0) {
            int groups = keyByte.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
            keyByte = temp;
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte,AES);

        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(decoder.decode(AES_IV)));

        byte[] base64 = decoder.decode(content);

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

        return new String(result, Charset.forName(ENCODE));
    }

    /**
     * Rsa生成公钥,密钥
     * @return 返回公钥,密钥字符串数组 0--密钥 1--公钥
     * @throws NoSuchAlgorithmException 异常信息
     */
    public static String[] RsaGenera() throws NoSuchAlgorithmException {
        // 1.初始化发送方密钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(512);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String[] results = new String[2];
        results[0] = Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded());
        results[1] = Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded());
        return results;
    }

    /**
     * Rsa私钥加密
     * @param privateKey 私钥
     * @param content 明文
     * @return 返回密文
     * @throws Exception 异常
     */
    public static String RsaPrivateEncrypt(String privateKey,String content) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey1);
        byte[] result = cipher.doFinal(content.getBytes(ENCODE));
        //System.out.println("私钥加密、公钥解密 ---- 加密:" + Arrays.toString(result));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * Rsa公钥解密
     * @param publicKey 公钥
     * @param content 密文
     * @return 明文
     * @throws Exception 异常
     */
    public static String RsaPublicUnEncrypt(String publicKey,String content) throws Exception{
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey1 = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey1);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
        //System.out.println("私钥加密、公钥解密 ---- 解密:" + Base64.getEncoder().encodeToString(result));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * Rsa公钥加密
     * @param publicKey 公钥
     * @param content 明文
     * @return 密文
     * @throws Exception 异常
     */
    public static String RsaPublicEncrypt(String publicKey,String content) throws Exception{
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey1 = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey1);
        byte[] result = cipher.doFinal(content.getBytes(ENCODE));
        //System.out.println("公钥加密、私钥解密 ---- 加密: "+Base64.getEncoder().encodeToString(result2));
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * Rsa私钥解密
     * @param privateKey 私钥
     * @param content 密文
     * @return 解密后明文
     * @throws Exception 异常
     */
    public static String RsaPrivateUnEncrypt(String privateKey,String content) throws Exception{
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey1);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
        //System.out.println("公钥加密、私钥解密 ---- 解密:" + new String(result));
        return new String(result);
    }

    public static void main(String[] args) throws Exception {
        String[] keys = RsaGenera();

        String aes_key = RsaPublicEncrypt(keys[1],AES_KEY);
        String aes_iv = RsaPublicEncrypt(keys[1],AES_IV);

        String AES_KEY = RsaPrivateUnEncrypt(keys[0],aes_key);
        String AES_IV = RsaPrivateUnEncrypt(keys[0],aes_iv);

        String m = AESEncryptEncode("今天打老虎",AES_IV,AES_KEY);
        System.out.println("AES对称加密: "+m);
        System.out.println("AES对称解密:"+AESDecodeDecrypt(m,AES_IV,AES_KEY));
    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值