• 密码学 aes rsa 分段加密 填充 rsakey 生成


    1 可逆加密/解密

    1.1 BASE64
      private static  final  String UTF8= StandardCharsets.UTF_8.name();
    
        //base64 加密 = 为补充字节,如果gbk 为3个字节编码, utf8 为4个字节编码
        @Test
         public  void  test1()throws  Exception{
    
            String  word = "刘必君1234";
    
            String encode = Base64.encodeBase64String(word.getBytes(UTF8));
            log.info("加密后的密串: "+ encode);
            // 5YiY5b+F5ZCbMTIzNA==
    
        }
    //     base64 解密
        @Test
        public  void  test2()throws  Exception{
    
            String  word = "5YiY5b+F5ZCbMTIzNA==";
    
            byte[] decode = Base64.decodeBase64(word);
    
            log.info("解密后的密串"+ new String(decode,UTF8));
            //刘必君1234
    
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2 不可逆加密

    2.1 MD5
      @Test
         public  void  test1()throws  Exception{
          
           private static  final  String UTF8= StandardCharsets.UTF_8.name();
    
            String  word = "刘必君1234";
    //        String algorithm = "MD5";
            String result = DigestUtils.md5Hex(word.getBytes(UTF8));
    
            log.info("算法对象加密结果长度:"+ result.length());
            log.info("算法对象加密结果:"+ result);
    //        64d409fa15a3bc4678f073f9f847f2eb
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    2.2 SHA256
     private static  final  String UTF8= StandardCharsets.UTF_8.name();
    
    
        @Test
         public  void  test1()throws  Exception{
    
            String  word = "刘必君1234";
    
            String result = DigestUtils.sha256Hex(word.getBytes(UTF8));
    //96cb3e8514fc85ef78a1b0c0ebdb0cb852266c04709719cf18475b07c911f011   64
            log.info("算法对象加密结果长度:"+ result.length());
            log.info("算法对象加密结果:"+ result);
    //        64d409fa15a3bc4678f073f9f847f2eb
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.3 SHA512
     private static  final  String UTF8= StandardCharsets.UTF_8.name();
    
    
        @Test
         public  void  test1()throws  Exception{
    
            String  word = "刘必君1234";
    
            String result = DigestUtils.sha512Hex(word.getBytes(UTF8));
    //b79555568ce9b19a8e4565f0b19ff7f947587b7ca4d03c9df0a18c0b6919d060add6220db510ecbfc271a9db4e5b4bff561f0b7ea48ad0262fe2dab9fa5a27ed   128
            log.info("算法对象加密结果长度:"+ result.length());
            log.info("算法对象加密结果:"+ result);
    //        64d409fa15a3bc4678f073f9f847f2eb
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.4 MAC加密

    mac 加密中使用了盐 ,key

     @Test
         public  void  test1()throws  Exception{
    
            String  word = "刘必君1234";
           String  key = "1231";
            String hmacHex = new HmacUtils(HmacAlgorithms.HMAC_MD5, key).hmacHex(word);
    //        3475e3498e6813d825523cdeadd8e172
            System.out.println(hmacHex);
    
    
    
            String HMAC_SHA_256 = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmacHex(word);
    //        29d732bdd062173e4bdb4f7d71d6ea6e44ad52d37e19c14cba2f4bf876ded48e
            System.out.println(HMAC_SHA_256);
    
    
            String HMAC_SHA_512 = new HmacUtils(HmacAlgorithms.HMAC_SHA_512, key).hmacHex(word);
    //        792b3be46ff34d878a1ea806d376f3a2e2af58b032e37f21d07421158aabda07ae72ef0b041ebe2e9eb78bb2d5a8b9a7d59d85f869ed4d2b0fca58f68d40aa72
            System.out.println(HMAC_SHA_512);
    
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3 对称加密解密

    堆成加密解密,只有一个key

    3.1 des加密和解密

    DEC_KEY 长度必须是等于8

    package com.sxfz.word.util;
    
    import org.apache.commons.codec.binary.Base64;
    import org.junit.Test;
    
    import javax.crypto.*;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.UnsupportedEncodingException;
    import java.nio.charset.StandardCharsets;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class DESUtils {
    
        private static final String ALGORITHM = "DES";
        //DEC_KEY 长度必须是等于8
        private static final String KEY = "12345678";
        private static final String UTF8 = StandardCharsets.UTF_8.name();
    
    
        private String encrypt(String text) throws Exception {
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM);
    //       初始化加解密对象,设置key,和加密规则/解密规则
            cilper.init(Cipher.ENCRYPT_MODE, secretKey);
    //        cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal(text.getBytes(UTF8));
            System.out.println(Base64.encodeBase64String(doFinal));
            return Base64.encodeBase64String(doFinal);
        }
    
        private String dencrypt(String text) throws Exception {
    
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM);
    //       初始化加解密对象,设置key,和加密规则/解密规则
    //        cilper.init(Cipher.ENCRYPT_MODE, secretKey);
            cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal( Base64.decodeBase64(text.getBytes(UTF8)));
            System.out.println(new String(doFinal,UTF8));
            return new String(doFinal,UTF8);
        }
    
    
        @Test
        public void  test() throws  Exception{
            String text = "张三丰的故事123";
            String encrypt = encrypt(text);
            System.out.println("base64加密"+encrypt);
            System.out.println("解密"+dencrypt(encrypt));
        }
    }
    结果:
    
    wtm82GVgSJmS7Rkp1HpiysQwRhamDJMS
    base64加密wtm82GVgSJmS7Rkp1HpiysQwRhamDJMS
    张三丰的故事123
    解密张三丰的故事123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    3.2 AES加密和解密

    aes_key 长度可以为:16 24 32;

    package com.sxfz.word.util;
    
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.binary.Hex;
    import org.junit.Test;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.nio.charset.StandardCharsets;
    
    public class AESUtils {
    
        private static final String ALGORITHM = "AES";
        //       int[] AES_KEYSIZES = new int[]{16, 24, 32};  aeskey 长度为16 24 32 三种情况
        private static final String KEY = "1234567121211212";
        private static final String UTF8 = StandardCharsets.UTF_8.name();
    
        /**
         *
         * @param text
         * @return 加密后返回16进制字符串对象
         * @throws Exception
         */
        private String encrypt(String text) throws Exception {
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM);
    //       初始化加解密对象,设置key,和加密规则/解密规则
            cilper.init(Cipher.ENCRYPT_MODE, secretKey);
    //        cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal(text.getBytes(UTF8));
            System.out.println(Base64.encodeBase64String(doFinal));
            return Hex.encodeHexString(doFinal);
        }
    
        /**
         *
         * @param encodetext hex加密字符串
         * @return 返回明文字符串
         * @throws Exception
         */
        private String dencrypt(String encodetext) throws Exception {
    
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM);
    //       初始化加解密对象,设置key,和加密规则/解密规则
    //        cilper.init(Cipher.ENCRYPT_MODE, secretKey);
            cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal( Hex.decodeHex(text));
            System.out.println(new String(doFinal,UTF8));
            return new String(doFinal,UTF8);
        }
    
    
        @Test
        public void  test() throws  Exception{
            String text = "张三丰的故事123";
            String encrypt = encrypt(text);
            System.out.println("HEX加密"+encrypt);
            System.out.println("解密"+dencrypt(encrypt));
        }
    }
    
    jieguo:
    LzcrgFJ6/Sb4poX0HMANb334Eowv6MptsiqAQW9SGxM= base64加密 长度44
    HEX加密2f372b80527afd26f8a685f41cc00d6f7df8128c2fe8ca6db22a80416f521b13 hexString 长度64
    张三丰的故事123
    解密张三丰的故事123
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    3.3 优化秘钥

    通过key 生成指定长度的秘钥,通过秘钥然后再获取加密串,最后是用加密串来进行初始化 之前的秘钥

     /**
         *  通过key生成指定长度的可以
         * @param key
         * @return
         */
        private SecretKey generatorKey(String key)throws  Exception{
    //     创建keygenerator对象,可以根据传入的key生成一个指定长度的key
            KeyGenerator keyGenerator =KeyGenerator.getInstance(ALGORITHM);
    //      初始化 secureRandom,并指定生成指定长度key的算法
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
    
             secureRandom.setSeed(key.getBytes(UTF8));
             keyGenerator.init(128,secureRandom);
             SecretKey secretKey =keyGenerator.generateKey();
    //         这里是通过秘钥获取,加密串
            byte[] encoded = secretKey.getEncoded();
            System.out.println(Hex.encodeHexString(encoded));
    
            return  secretKey;
        }
    
    
    
        @Test
        public void  test() throws  Exception{
    //        String text = "张三丰的故事123";
    //        String encrypt = encrypt(text);
    //        System.out.println("HEX加密"+encrypt);
    //        System.out.println("解密"+dencrypt(encrypt));
    
    
            generatorKey("123");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    3.4 加密分类
    3.4.1 块加密
    • ECB

      定义:electronic code book ,电码本模式,将整个明文分成若干段相同的小段,然后对每一段进行加密

      特点:每段之间互不依赖,可以并行处理;同样的明文总是成成同样的密文

    在这里插入图片描述

    • CBC

      定义:cipher block chanining ,密文分组链模式,所谓的链,即密文分组之间像联调一样相关链接在一起,先将明文切分若干小段,然后每一小段与上一段的密文段(第一个块因每一上一个密文段,使用的是IV)进行运算后,在与秘钥进行加密;

      特点: 串行处理;同样的明文每次生成的密文不一样

      IV:为初始化向量

    在这里插入图片描述

    3.4.2 序列加密
    3.5 块加密常用的填充模式

    为什么要有,对于固定的加密算法,每个块有固定的大小(blocksize),比如8个byte,明文分块后,加密前需要保证最后一个块的大小为8个byte,如果不够则使用特定的数据进行填充;

    • noPadding : 不自动填充

      desc时,要求明文必须是8个字节的整数倍,aes时,是16个字节的整数倍

    • PKCS5Padding(限制了块大小为8个byte的)PKCS7Padding

    • ECB 加密:

    package com.sxfz.word.util;
    
    import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.binary.Hex;
    import org.junit.Test;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.nio.charset.StandardCharsets;
    import java.security.SecureRandom;
    
    public class AESUtils {
    
        private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
        private static final String ALGORITHM_TYPE = "AES";
    //       int[] AES_KEYSIZES = new int[]{16, 24, 32};  aeskey 长度为16 24 32 三种情况
        private static final String KEY = "1234567121211211";
        private static final String UTF8 = StandardCharsets.UTF_8.name();
    
        /**
         *
         * @param text
         * @return 加密后返回16进制字符串对象
         * @throws Exception
         */
        private String encrypt(String text) throws Exception {
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM_TYPE);
    //       初始化加解密对象,设置key,和加密规则/解密规则
            cilper.init(Cipher.ENCRYPT_MODE, secretKey);
    //        cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal(text.getBytes(UTF8));
            System.out.println(Base64.encodeBase64String(doFinal));
            return Hex.encodeHexString(doFinal);
        }
    
        /**
         *
         * @param encodetext hex加密字符串
         * @return 返回明文字符串
         * @throws Exception
         */
        private String dencrypt(String encodetext) throws Exception {
    
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM_TYPE);
    //       初始化加解密对象,设置key,和加密规则/解密规则
    //        cilper.init(Cipher.ENCRYPT_MODE, secretKey);
            cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal( Hex.decodeHex(encodetext));
            System.out.println(new String(doFinal,UTF8));
            return new String(doFinal,UTF8);
        }
    
      
    
    
        @Test
        public void  test() throws  Exception{
            String text = "张三丰的故事123";
            String encrypt = encrypt(text);
            System.out.println("HEX加密"+encrypt);
            System.out.println("解密"+dencrypt(encrypt));
    
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • cbc 加密机制
    package com.sxfz.word.util;
    
    import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.binary.Hex;
    import org.junit.Test;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.nio.charset.StandardCharsets;
    import java.security.SecureRandom;
    
    public class AESUtils {
    
        private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
        private static final String ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
        private static final String ALGORITHM_TYPE = "AES";
    //       int[] AES_KEYSIZES = new int[]{16, 24, 32};  aeskey 长度为16 24 32 三种情况
        private static final String KEY = "1234567121211211";
    //    IV 的默认长度为16个字节
        private static final String IV = "abcdefgh12345678";
        private static final String UTF8 = StandardCharsets.UTF_8.name();
    
        /**
         *
         * @param text
         * @return 加密后返回16进制字符串对象
         * @throws Exception
         */
        private String encrypt(String text) throws Exception {
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM_CBC);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM_TYPE);
    //       初始化加解密对象,设置key,和加密规则/解密规则
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(UTF8));
    //        cilper.init(Cipher.DECRYPT_MODE,secretKey);
            cilper.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec);
    //        cilper.init(Cipher.DECRYPT_MODE,secretKey);
    
            byte[] doFinal = cilper.doFinal(text.getBytes(UTF8));
    
            return Hex.encodeHexString(doFinal);
        }
    
        /**
         *
         * @param encodetext hex加密字符串
         * @return 返回明文字符串
         * @throws Exception
         */
        private String dencrypt(String encodetext) throws Exception {
    
    //      获取实例
            Cipher cilper = Cipher.getInstance(ALGORITHM_CBC);
    //      创建 加密的规则
    
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM_TYPE);
    //       初始化加解密对象,设置key,和加密规则/解密规则
    //        cilper.init(Cipher.ENCRYPT_MODE, secretKey);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(UTF8));
    //        cilper.init(Cipher.DECRYPT_MODE,secretKey);
            cilper.init(Cipher.DECRYPT_MODE,secretKey,ivParameterSpec);
    
            byte[] doFinal = cilper.doFinal( Hex.decodeHex(encodetext));
            System.out.println(new String(doFinal,UTF8));
            return new String(doFinal,UTF8);
        }
    
        /**
         *  通过key生成指定长度的可以
         * @param key
         * @return
         */
        private SecretKey generatorKey(String key)throws  Exception{
    //     创建keygenerator对象,可以根据传入的key生成一个指定长度的key
            KeyGenerator keyGenerator =KeyGenerator.getInstance(ALGORITHM);
    //      初始化 secureRandom,并指定生成指定长度key的算法
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
    
             secureRandom.setSeed(key.getBytes(UTF8));
             keyGenerator.init(128,secureRandom);
             SecretKey secretKey =keyGenerator.generateKey();
    //         这里是通过秘钥获取,加密串
            byte[] encoded = secretKey.getEncoded();
            System.out.println(Hex.encodeHexString(encoded));
    
            return  secretKey;
        }
    
    
    
        @Test
        public void  test() throws  Exception{
            String text = "我是超人我怕谁,212123";
            String encrypt = encrypt(text);
            System.out.println("HEX加密"+encrypt);
            System.out.println("解密"+dencrypt(encrypt));
    
    
    //        generatorKey("123");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107

    4 非对称加密

    4.1 定义

    加密和解密使用两个不通的秘钥,(public key和private key)公钥可以给别人私钥总是字节保留。

    4.2 为什么会出现

    对称加密使用相同的秘钥,但对不同的原始内容加密会采用不同的秘钥,导致秘钥数量巨大,难以维护。

    4.3 常见算法
    • RSA
    • 其他:ECC , Diffe-Hellman, EI Gamal ,DSA
    5.3 应用场景
    • 加解密

      可以使用公钥加密,对应的就是私钥解密;也可以使用私钥加密,对应的是公钥解密;

    package com.sxfz.word.util;
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.io.FileUtils;
    import org.junit.Test;
    
    
    import javax.crypto.Cipher;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.nio.charset.StandardCharsets;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    /**
     * RAS 加密解密工具类
     */
    @Slf4j
    public class RsaUtils {
    
        private static final String ALGORITHM = "RSA";
        private static final String UTF8 = StandardCharsets.UTF_8.name();
    //  单次加密长度最大为117
        private static final int MAX_ENCODE_LENGTH = 117;
        //  单次解密长度最大为128
        private static final int MAX_DECODE_LENGTH = 128;
    
    
        private static String publicKeyPath;
        private static String privateKeyPath;
    
    
        static {
            ClassLoader classLoader = RsaUtils.class.getClassLoader();
            publicKeyPath = classLoader.getResource("rsa.pub").getPath();
            privateKeyPath = classLoader.getResource("rsa.pri").getPath();
    
            log.info("publicKeyPath"+publicKeyPath);
            log.info("privateKeyPath"+privateKeyPath);
        }
    
        /**
         * 生成经过base64加密(公钥/私钥),并写入到文件中
         */
        private void writeRsaKey2File()throws  Exception{
    
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
    
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();
    
            FileUtils.writeStringToFile(new File(publicKeyPath),Base64.encodeBase64String(publicKey.getEncoded()),UTF8);
            FileUtils.writeStringToFile(new File(privateKeyPath),Base64.encodeBase64String(privateKey.getEncoded()),UTF8);
    
    
        }
    
    
    
        /**
         *  从生成好的文件中获取公钥
         *  公钥和私钥保存在文件中是使用base64的方式进行编码的,所以第一步需要进行base64解码
         *   公钥使用规则 X509EncodedKeySpec
         *   私钥使用规则  PKCS8EncodedKeySpec
         * @return
         */
        private PublicKey getPublicKey()throws  Exception{
            String endcodeBase64 = FileUtils.readFileToString(new File(publicKeyPath), UTF8);
            byte[] publicKeyBytes = Base64.decodeBase64(endcodeBase64);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    //      公钥使用规则x509
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyBytes);
            return keyFactory.generatePublic(x509EncodedKeySpec);
    
        }
    
        /**
         *  从生成好的文件中获取私钥
         *  公钥和私钥保存在文件中是使用base64的方式进行编码的,所以第一步需要进行base64解码
         *   公钥使用规则x509
         *       私钥使用规则  PKCS8EncodedKeySpec
         * @return
         */
        private PrivateKey getPrivateKey()throws  Exception{
            String endcodeBase64 = FileUtils.readFileToString(new File(privateKeyPath), UTF8);
            byte[] privateKeyBytes = Base64.decodeBase64(endcodeBase64);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    //       私钥使用规则  PKCS8EncodedKeySpec
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        }
    
        @Test
        public void test1()throws  Exception{
    //        生成秘钥对  生成一次后保存下来,不要乱折腾
    //        writeRsaKey2File();
            String  text = "搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;搜晚上我是超人,我怕谁12132l;";
            System.out.println(" ------------------公钥加密,私钥解密-------------------------------");
            String encryptStr = encrypt(text, getPublicKey());
            System.out.println(encryptStr);
            String decryptStr = decrypt(encryptStr, getPrivateKey());
            System.out.println(decryptStr);
            System.out.println(" ------------------私钥加密,公钥解密-------------------------------");
    
             encryptStr = encrypt(text,getPrivateKey());
            System.out.println(encryptStr);
             decryptStr = decrypt(encryptStr,getPublicKey());
            System.out.println(decryptStr);
    
    
    
    
        }
    
    
        /**
         *  加密类
         * @param originalContent 要加密的明文
         * @param key 公钥或者私钥
         * @return Base64 加密后的字符串
         */
        private String encrypt(String originalContent, Key key) throws  Exception{
    
    
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE,key);
    
            byte []  bytes = doCodec(cipher,originalContent.getBytes(UTF8),MAX_ENCODE_LENGTH);
    
            return Base64.encodeBase64String(bytes);
    
        }
    
    
    
        /**
         *  解密类
         * @param base64EncodeContent base64加密后的密文
         * @param key 公钥或者私钥
         * @return 原始内容
         */
        private String decrypt(String base64EncodeContent, Key key) throws  Exception{
    
            byte[] decodeBase64 = Base64.decodeBase64(base64EncodeContent);
    
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE,key);
    
            byte []  bytes = doCodec(cipher,decodeBase64,MAX_DECODE_LENGTH);
    
            return  new String(bytes,UTF8);
    
        }
    
        /**
         *   加密/解密的公共方法
         * @param cipher 加密或者解密
         * @param bytes 明文/密文
         * @param maxBlockSize 处理的最大长度
         * @return  返回密文或者明文
         * @throws Exception
         */
        private byte[] doCodec(Cipher cipher, byte[] bytes, int maxBlockSize) throws Exception{
    //       偏移量
            int offset = 0;
    
    //       循环成次数
            int count = 0 ;
    //      加密/解密后的结果
            byte []  temp;
    //      加密/解密的总结果
            ByteArrayOutputStream  bos = new ByteArrayOutputStream();
    
    //        输入的字符串长度
            int inputLength = bytes.length;
    
    
            while ((inputLength - offset)>0){
    
                if((inputLength - offset)>maxBlockSize){
                temp =  cipher.doFinal(bytes,offset,maxBlockSize);
                }else {
    
                  temp =  cipher.doFinal(bytes,offset,inputLength - offset);
                }
                bos.write(temp,0,temp.length);
                count ++;
                offset = maxBlockSize*count;
    
            }
    
    
            byte[] result = bos.toByteArray();
            bos.close();
    
            return  result;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 数字签名
    • 数字信封
    • 数字证书
  • 相关阅读:
    竖曲线全线计算
    v-html指令怎么防止XSS注入
    Exception_json反序列化失败_JSONException
    数据库学习
    java计算机毕业设计学生生活管理源码+系统+数据库+lw文档
    就是一整个爱住,你们大胆飞,我就是最坚强的后盾——Java面试突击宝典
    OpenCloudOS 开源操作系统社区成立;Azure 漏洞暴露数百个源代码存储库;AWS 遭遇本月第三次中断| 开源日报
    【pygame】01 pygame制作游戏的最小系统
    容器数据卷+MYSQL实战
    Cygwin使用心得
  • 原文地址:https://blog.csdn.net/shi860715/article/details/126390136