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

版权声明:转载请注明出处 https://blog.csdn.net/chenmingxu438521/article/details/91616620

一、什么是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加密。晚安各位!!!

猜你喜欢

转载自blog.csdn.net/chenmingxu438521/article/details/91616620