欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一、关于接口安全加密传输对称加密与非对称加密的理解

程序员文章站 2022-05-15 16:59:43
...

一、什么是URL转码

1.不管是以何种方式传递url时,如果要传递的url中包含特殊字符,如想要传递一个+,但是这个+会被url会被编码成空格,想要传递&,被url处理成分隔符。 尤其是当传递的url是经过Base64加密或者RSA加密后的,存在特殊字符时,这里的特殊字符一旦被url处理,就不是原先你加密的结果了。

2.url特殊符号及对应的编码:

符号

url中的含义

编码

+

URL 中+号表示空格

%2B

空格

URL中的空格可以用+号或者编码

%20

/

分隔目录和子目录

%2F

?

 

 

 

 

 

 

 

 

分隔实际的URL和参数

%3F

%

指定特殊字符

%25

#

表示书签

%23

&

URL中指定的参数间的分隔符

%26

=

URL中指定参数的值

%3D

3.举个例子

3.1.项目结构

一、关于接口安全加密传输对称加密与非对称加密的理解

3.2.IndexController.java

//http协议特殊字符处理
@RestController
public class IndexController {
    //1.什么是特殊字符处理(rpc远程通讯 实现加密)
    @RequestMapping("/indexPage")
    public String indexPage(String userName){
        System.out.println("userName"+userName);
        return userName;
    }
}

3.3.访问结果(传入的结果传入+参数变为了空格)

一、关于接口安全加密传输对称加密与非对称加密的理解

3.4.解决办法:将+变为%2B(根据上面的表格转化一下)

一、关于接口安全加密传输对称加密与非对称加密的理解

二、什么是对称加密?

1.就是加密和解密都是同一个**,在加解密过程当中,使用的是同一个**进行加解密。

2.DES(数据加密标准):分组式加密,算法源于Lucifer,作为NIST对称式加密标准;64位(有效位56位、校验8位),分组算法

  3DES:128位,分组算法

  IDEA(国际数据加密算法):128位,比DES快,分组算法

  Blowfish:32-448位,算法公开,分组算法

  RC4:流密码,**长度可变

  RC5:分组密码,**长度可变,最大2048位

  Rijndael:128位/196位/256位

  AES(高级加密标准):DES升级版,算法出自Rinjindael

三、DES加密(对称加密)

1.代码例子

/**
 * DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同**的算法。DES加密算法出自IBM的研究,
 * 后来被美国*正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位**,以现代计算能力,
 * 24小时内即可被**。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 。
 * 注意:DES加密和解密过程中,**长度都必须是8的倍数
 */
public class DES {
    public DES() {
    }
    // 测试
    public static void main(String args[]) throws Exception {
        // 待加密内容
        String str = "chenmingxu1314";
        // 密码,长度要是8的倍数 **随意定
        String password = "13145210";
        byte[] encrypt = encrypt(str.getBytes(), password);
        System.out.println("加密后:" + new String(encrypt));
        // 解密
        byte[] decrypt = decrypt(encrypt, password);
        System.out.println("解密后:" + new String(decrypt));
    }

    /**
     * 加密
     *
     * @param datasource byte[]
     * @param password   String
     * @return byte[]
     */
    public static byte[] encrypt(byte[] datasource, String password) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            // 创建一个密匙工厂,然后用它把DESKeySpec转换成
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            // 现在,获取数据并加密
            // 正式执行加密操作
            return cipher.doFinal(datasource); // 按单部分操作加密或解密数据,或者结束一个多部分操作
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密
     *
     * @param src      byte[]
     * @param password String
     * @return byte[]
     * @throws Exception
     */
    public static byte[] decrypt(byte[] src, String password) throws Exception {
        // DES算法要求有一个可信任的随机数源
        SecureRandom random = new SecureRandom();
        // 创建一个DESKeySpec对象
        DESKeySpec desKey = new DESKeySpec(password.getBytes());
        // 创建一个密匙工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回实现指定转换的
        // Cipher
        // 对象
        // 将DESKeySpec对象转换成SecretKey对象
        SecretKey securekey = keyFactory.generateSecret(desKey);
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, random);
        // 真正开始解密操作
        return cipher.doFinal(src);
    }
}

2.结果

加密后:%��kJK�;�n�Y�}
解密后:chenmingxu1314

3.对称加密优缺点

3.1.缺点:同一个**,如果前端传到后台用到这个加密的话,如果别人拿到你的源码,反编译之后就有可能获取到你的**,所以说这样是很不安全的。

3.2.优点:速度非常快,使用场景是后台与后台之间的通信,举个例子,机构网站与机构网站进行合作的情况下可以使用对称加密。

四、什么是非对称加密(RSA)?

1.首先非对称加密,分为一对**(必须组合公钥和私钥进行组合)。

2.使用第三方工具生成非对称**对。

3.如果使用公钥加密,那么必须要使用私钥解密。

   如果使用私钥加密,那么必须要使用公钥解密。

   公钥加密------私钥解密(安全),很常用。

    私钥加密------公钥解密。

4.目前来说是最安全的加密手段,缺点:效率低,应用场景:第三方支付对接、核心金融机构。

五、RSA代码

1.代码例子

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

    public static String publicKey; // 公钥
    public static String privateKey; // 私钥

    /**
     * 生成公钥和私钥
     */
    public static void generateKey() {
        // 1.初始化秘钥
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            SecureRandom sr = new SecureRandom(); // 随机数生成器
            keyPairGenerator.initialize(512, sr); // 设置512位长的秘钥
            KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 开始创建
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 进行转码
            publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
            // 进行转码
            privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 私钥匙加密或解密
     *
     * @param content
     * @param privateKeyStr
     * @return
     */
    public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {
        // 私钥要用PKCS8进行处理
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
        KeyFactory keyFactory;
        PrivateKey privateKey;
        Cipher cipher;
        byte[] result;
        String text = null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            // 还原Key对象
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(opmode, privateKey);
            if (opmode == Cipher.ENCRYPT_MODE) { // 加密
                result = cipher.doFinal(content.getBytes());
                text = Base64.encodeBase64String(result);
            } else if (opmode == Cipher.DECRYPT_MODE) { // 解密
                result = cipher.doFinal(Base64.decodeBase64(content));
                text = new String(result, "UTF-8");
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return text;
    }

    /**
     * 公钥匙加密或解密
     *
     * @param content
     * @param privateKeyStr
     * @return
     */
    public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {
        // 公钥要用X509进行处理
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
        KeyFactory keyFactory;
        PublicKey publicKey;
        Cipher cipher;
        byte[] result;
        String text = null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            // 还原Key对象
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(opmode, publicKey);
            if (opmode == Cipher.ENCRYPT_MODE) { // 加密
                result = cipher.doFinal(content.getBytes());
                text = Base64.encodeBase64String(result);
            } else if (opmode == Cipher.DECRYPT_MODE) { // 解密
                result = cipher.doFinal(Base64.decodeBase64(content));
                text = new String(result, "UTF-8");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return text;
    }

    // 测试方法
    public static void main(String[] args) {
        /**
         * 注意: 私钥加密必须公钥解密 公钥加密必须私钥解密
         */
        System.out.println("-------------生成两对秘钥,分别发送方和接收方保管-------------");
        RSAUtil.generateKey();
        System.out.println("公钥匙给接收方:" + RSAUtil.publicKey);
        System.out.println("私钥给发送方:" + RSAUtil.privateKey);

        System.out.println("-------------第一个栗子,私钥加密公钥解密-------------");
        // String textsr = "早啊,你吃早饭了吗?O(∩_∩)O~";
        // // 私钥加密
        // String cipherText = RSAUtil.encryptByprivateKey(textsr,
        // RSAUtil.privateKey, Cipher.ENCRYPT_MODE);
        // System.out.println("发送方用私钥加密后:" + cipherText);
        // // 公钥解密
        // String text = RSAUtil.encryptByPublicKey(cipherText,
        // RSAUtil.publicKey, Cipher.DECRYPT_MODE);
        // System.out.println("接收方用公钥解密后:" + text);

        System.out.println("-------------第二个栗子,公钥加密私钥解密-------------");
        // 公钥加密
        String textsr = "吃过啦!你吃了吗?O(∩_∩)O~";

        String cipherText = RSAUtil.encryptByPublicKey(textsr, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);
        System.out.println("接收方用公钥加密后:" + cipherText);
        // 私钥解密
        String text = RSAUtil.encryptByprivateKey(cipherText, RSAUtil.privateKey, Cipher.DECRYPT_MODE);
        System.out.print("发送方用私钥解密后:" + text);
    }
}

2.测试代码

public class Test001 {

	public static void main(String[] args) {
		// 实现步骤:
		// 1.生成公钥和私钥**对
		RSAUtil.generateKey();
		System.out.println("私钥:" + RSAUtil.privateKey);
		System.out.println("公钥:" + RSAUtil.publicKey);
		String content = "chenmingxu1314";
		// 2.使用公钥进行加密
		String encryptByPublicKey = RSAUtil.encryptByPublicKey(content, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);
		System.out.println("加密后:" + encryptByPublicKey);
		String encryptByprivateKey = RSAUtil.encryptByprivateKey(encryptByPublicKey, RSAUtil.privateKey,
				Cipher.DECRYPT_MODE);
		// 3.使用私钥进行解密
		System.out.println("解密后:" + encryptByprivateKey);
		// 正常在开发中的时候,后端开发人员生成好**对,服务器端保存私钥 客户端保存公钥
	}
}

3.测试结果

私钥:MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAsyohB5wXqQgR+BB9MNGIsux0VgxBhyDmwUKVTtDYAr4pMdRahsYZ21nWwHkQMwl4Psio2r+9Rfb2qWsrbY4xSQIDAQABAkBNyvUcgMIlOsPSmhZBpDletxysYBXzvm1zbJ234yZnybz2Ye4qlRc28r6YF7tJXJV4yRDdFBm85wmVLFjmxZ8hAiEA/wWbo5HueQ1DsE3E3VIDskHqHIWStOEdi07zlgKA+88CIQCz2gp38P+gslwzKU8MpxZWUBSnxTCR68mZcuJC+8xPZwIhANSNeQZhGDEexB8LAp0wwVHurFDvZ7KIupYkzNNn7NdzAiEAgkpB7TQMq+iqPHH/j0X4O50V6ZhDoGJ1EJIWcboh/58CICLbWBPQNxWfn0bgTKLCnQwbvM1lYA5/mygFlMUTU7QP
公钥:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALMqIQecF6kIEfgQfTDRiLLsdFYMQYcg5sFClU7Q2AK+KTHUWobGGdtZ1sB5EDMJeD7IqNq/vUX29qlrK22OMUkCAwEAAQ==
加密后:rcdusr+460g9KOkeybQwpE2o/pg+x4eMFn7JdxBRUReHTP3mZJDUPQ9jenW+g8OHN1veo/7azNA4Nb5S043ekg==
解密后:chenmingxu1314

六、结束

今天就写到这里吧,有时间再研究下MD5加密。晚安各位!!!