• java加解密(一)


    1、杂谈

      1、古典密码学

        核心:替换法/位移法(凯撒加密)

        破解方法:频率分析法,即研究字母和字母组合在文本中出现的概率。

      2、近代密码学:

        恩尼格玛机

        被图灵破解

      3、现代密码学:

        1、散列函数:散列函数,也叫杂凑函数、摘要函数或哈希函数,可将任意长度的消息经过运算,变成固定长度数值,常见的有MD5SHA-1SHA256,多应用在文件校验,数字签名中。

        2、对此密码:对称密码应用了相同的加密密钥和解密密钥。对称密码分为:序列密码(流密码),分组密码(块密码)两种。流密码是对信息流中的每一个元素(一个字母或一个比特)作为基本的处理单元进行加密,块密码是先对信息流分块,再对每一块分别加密。

        3、非对称密码:非对称密码有两支密钥,公钥(publickey)和私钥(privatekey),加密和解密运算使用的密钥不同。用公钥对原文进行加密后,需要由私钥进行解密;用私钥对原文进行加密后(此时一般称为签名),需要由公钥进行解密(此时一般称为验签)。公钥可以公开的,大家使用公钥对信息进行加密,再发送给私钥的持有者,私钥持有者使用私钥对信息进行解密,获得信息原文。因为私钥只有单一人持有,因此不用担心被他人解密获取信息原文。

    2、常见加密模式(部分代码可直接复用)

      1、单密钥加密:DES加密/AES加密

    /**
     * @Description DES对称加密标准,单密钥加密
     * @Author lx
     * @Date 2020/12/15 16:05
     **/
    public class DESDemo {
    ​
        public static void main(String[] args) throws Exception {
            //1.原文
            String str = "下雪了";
            System.out.println("原文:"+str);
            //2.key,DES的加密key必须是8位
            String key ="12345678";
    ​
            /**
             * AES和DES区别
             * 1.DES比AES原始
             * 2.DES密钥必须是8位数组   :mQRnQ+PLy3s5e6I2UFZGNW0cmZX2Z+ON
             * 3.AES密钥是16位密钥,其他代码几乎一样 :dydk4yvmMOchvAyXCKuPIgf+U13Kia5U3w53KFaKnyE=
             * 4.加密后的结果不一样
             */
            //3.算法,DES
            String algorithm = "DES";
    ​
            //4.形式,模式
            String transformation = "DES";
    ​
            //5.获取加密对象
            Cipher cipher = Cipher.getInstance(transformation);
    ​
            //6.指定密钥规则
            //传入2个参数:1.密钥key,必须是8位字节数组;2.alogrithm 算法;
            //返回SecretKeySpec,密钥规则
            //       SecretKeyFactory factory = SecretKeyFactory.getInstance(key.getBytes(), algorithm);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
            /**
             * 对加密进行初始化
             * 传入2 个参数:1.模式,加密模式或者解密模式;2.加密规则
             */
            cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);
    ​
            //进行加密
            byte[] bytes = cipher.doFinal(str.getBytes());
    ​
            /**
             * 打印密文,直接打印乱码,需要用base64进行转换
             * 注意:tostring和new string()区别
             * 1.tostring():用于打印hash地址或者对象
             * 2.new String():用于打印密文
             */
            System.out.println("未进行base64转码前加密结果:"+new String(bytes));
    ​
            /**
             * base64.encode()对密文进行解码,便于查看
             * base64.decode()对密文进行转码,转回成密文
             */
            System.out.println("进行base64转码后的加密结果:"+Base64.encode(bytes));
    ​
        }
    }

    运行结果:

    原文:下雪了
    未进行base64转码前加密结果:r�w��5���T�.�Am�
    进行base64转码后的加密结果:csB3veA1qbGUVIoujUFthw==

      2、AES/EDS解密

    public class AesDemo {
        // DES加密算法,key的大小必须是8个字节
    public static void main(String[] args) throws Exception {
            String input ="原文";
            // AES加密算法,比较高级,所以key的大小必须是16个字节
            String key = "1234567812345678";
    ​
            String transformation = "AES"; // 9PQXVUIhaaQ=
            // 指定获取密钥的算法
            String algorithm = "AES";
            // 先测试加密,然后在测试解密
            String encryptDES = encryptDES(input, key, transformation, algorithm);
            System.out.println("加密:" + encryptDES);
            String s = dncryptDES(encryptDES, key, transformation, algorithm);
            System.out.println("解密:" + s);
    ​
        }
    ​
        /**
         * 使用DES加密数据
         *
         * @param input          : 原文
         * @param key            : 密钥(DES,密钥的长度必须是8个字节)
         * @param transformation : 获取Cipher对象的算法
         * @param algorithm      : 获取密钥的算法
         * @return : 密文
         * @throws Exception
         */
        private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
            // 获取加密对象
            Cipher cipher = Cipher.getInstance(transformation);
            // 创建加密规则
            // 第一个参数key的字节
            // 第二个参数表示加密算法
            SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
            // ENCRYPT_MODE:加密模式
            // DECRYPT_MODE: 解密模式
            // 初始化加密模式和算法
            cipher.init(Cipher.ENCRYPT_MODE,sks);
            // 加密
            byte[] bytes = cipher.doFinal(input.getBytes());
    ​
            // 输出加密后的数据
            String encode = Base64.encode(bytes);
    ​
            return encode;
        }
    ​
        /**
         * 使用DES解密
         *
         * @param input          : 密文
         * @param key            : 密钥
         * @param transformation : 获取Cipher对象的算法
         * @param algorithm      : 获取密钥的算法
         * @throws Exception
         * @return: 原文
         */
        private static String dncryptDES(String input, String key, String transformation, String algorithm) throws Exception {
            // 1,获取Cipher对象
            Cipher cipher = Cipher.getInstance(transformation);
            // 指定密钥规则
            SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
            cipher.init(Cipher.DECRYPT_MODE, sks);
            // 3. 解密
            byte[] bytes = cipher.doFinal(Base64.decode(input));
    ​
            return new String(bytes);
        }
    }

    运行结果:

     加密:TUuxDy0h/Rx1KwhMFXEnog==
     解密:原文

      3、加密模式:ECB/CBC

      4、填充模式

    3、消息摘要

    /**
     * @Description 消息摘要
     * @Author lx
     * @Date 2020/12/15 16:38
     **/
    public class DigestDemo {
    ​
        public static void main(String[] args) throws Exception {
            /**
             * 获取消息摘要
             */
            //1.原文
            String  str  = "消息摘要";
    ​
            //2.算法,MD5
            String algorithm ="MD5";
            String MD5 = getDigest(str, algorithm);
            System.out.println("MD5--->"+MD5);
    ​
            /**
             * 使用不同算法,生成消息数字摘要
             */
            algorithm ="SHA-1";
            String SHA1 = getDigest(str, algorithm);
            System.out.println("SHA1--->"+SHA1);
    ​
            algorithm ="SHA-256";
            String SHA256 = getDigest(str, algorithm);
            System.out.println("SHA256--->"+SHA256);
    //7b0feaed8d7291cbaf1139e85ec6318da6a18972ae5faf3d6dbefe5b21bbd7bd
    //7b0feaed8d7291cbaf1139e85ec6318da6a18972ae5faf3d6dbefe5b21bbd7bd
    //889a828bfcf3c9f7adf862c9cd051d5b961be308
    //        System.out.println(new String(digest));
    //
    //        System.out.println(Base64.encode(digest));
    //
            //323070dd4582eda3825fec99ee0887db
            //323070dd4582eda3825fec99ee887db
            //323070dd4582eda3825fec99ee0887db
        }
    ​
        /**
         * 因base64转码结果和直接用网页MD5生成密文不同
         * 生成数字摘要,传入不同算法,不使用base64进行转码,直接使用16进制进行转换,
         * 字符位数不足2的在高位补0
         * @param str   原文
         * @param algorithm  算法
         * @return
         * @throws NoSuchAlgorithmException
         */
        private static String  getDigest(String str, String algorithm) throws NoSuchAlgorithmException {
            //3.获取数字摘要对象
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
    ​
            //4.获取数字摘要的字节数组
            byte[] digest = messageDigest.digest(str.getBytes());
    ​
            StringBuffer sb = new StringBuffer();
    ​
            for (byte b : digest) {
                //将每个字节转成16进制
                String s = Integer.toHexString(b & 0xff);
                //直接打印会少2位
                //如果生成的字符只有一个,在高位补0
                if(s.length()==1){
                    s = "0"+s;
                }
                sb.append(s);
            }
           // System.out.println(sb);
            return  sb.toString();
        }
    }

    运行结果:

    MD5--->323070dd4582eda3825fec99ee0887db
    SHA1--->889a828bfcf3c9f7adf862c9cd051d5b961be308
    SHA256--->7b0feaed8d7291cbaf1139e85ec6318da6a18972ae5faf3d6dbefe5b21bbd7bd

     

  • 相关阅读:
    使用Python的requests库作接口测试——对HTTP动词的支持
    用Python的requests库作接口测试——对响应进行迭代
    用Python的requests库作接口测试——上传文件
    使用Python的requests库作接口测试——请求对象与响应对象
    Python程序的执行过程
    python Requests模块
    Linux命令CURL用法
    curl命令
    设计的七大原则
    深入理解多态 (1)
  • 原文地址:https://www.cnblogs.com/gaoyangsixue/p/14142570.html
Copyright © 2020-2023  润新知