暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

m2,sm3,sm4国密算法实现

IT学习道场 2022-07-19
1010

pom中引入


    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15to18</artifactId>
        <version>1.71</version>
    </dependency>


    <dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.0.3</version>
    </dependency>

    sm2非对称加密


    非对称加密,公钥加密,私钥解密

      package com.sm.sm2;


      import lombok.AllArgsConstructor;
      import lombok.Data;
      import lombok.NoArgsConstructor;


      /**
      * 描述: 国密算法生成秘钥对 - 对象 <br>
      * 时间: 2022-07-14 16:01 <br>
      * 作者:IT学习道场
      */
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class SM2KeyPairs {
      /**
      *公钥
      */
      private String publicKey;


      /**
      * 私钥
      */
      private String privateKey;
      }

      SM2非对称加密辅助类

        package com.sm.sm2;


        import cn.hutool.crypto.SmUtil;
        import cn.hutool.crypto.asymmetric.KeyType;
        import cn.hutool.crypto.asymmetric.SM2;


        /**
        * 描述: SM2非对称加密辅助类 <br>
        * 时间: 2022-07-14 16:01 <br>
        * 作者:IT学习道场
        */
        public class SM2Util {


        /**
        * 私钥解密
        * @param privateKey 私钥
        * @param text 加密文本
        * @return 解密后文本
        */
        public static String decrypt(String privateKey, String text){
        // 通过密钥解密
        SM2 sm2 = SmUtil.sm2(privateKey, null);
        String decryptText = sm2.decryptStr(text, KeyType.PrivateKey);
        return decryptText;
        }


        /**
        * 公钥加密
        * @param publicKey 公钥
        * @param text 预加密文本
        * @return 加密后文本
        */
        public static String encrypt(String publicKey, String text){
        // 通过密钥解密
        SM2 sm2 = SmUtil.sm2(null, publicKey);
        String encryptText = sm2.encryptBase64(text, KeyType.PublicKey);
        return encryptText;
        }


        /**
        * 获取公钥私钥
        * @return SM2KeyPairs 公私钥对象
        */
        public static SM2KeyPairs getKeyPairs(){
        SM2 sm = SmUtil.sm2();
        String privateKey = sm.getPrivateKeyBase64();
        String publicKey = sm.getPublicKeyBase64();
        SM2KeyPairs keyPairs = new SM2KeyPairs(publicKey, privateKey);
        return keyPairs;
        }




        }


        SM3国密算法辅助类 ,SM3混淆不可逆,类似 md5


          package com.sm.sm3;


          import cn.hutool.crypto.SmUtil;


          /**
          * 描述: SM3国密算法辅助类 ,SM3加密不可逆,类似 md5<br>
          * 时间: 2022-07-14 16:49 <br>
          * 作者:IT学习道场
          */
          public class SM3Util {


          public static void test() {
          String encrypt = encrypt("123456");
          System.out.println(encrypt);
          }


          public static String encrypt(String text) {
          String digestHex = SmUtil.sm3(text);
          return digestHex;
          }


          }




          国密SM4对称加密算法辅助类


          对称加密就是加密和解密都要同一个 密钥 key

            package com.sm.sm4;


            import cn.hutool.crypto.symmetric.SymmetricCrypto;
            /**
            * 描述: 国密SM4对称加密算法辅助类<br>
            * 时间: 2022-07-14 16:01 <br>
            * 作者:王
            */
            public class SM4Util {


            //key必须是16字节,即128位
            final static String key = "sm4demo123456789";


            //指明加密算法和秘钥
            static SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", key.getBytes());


            //加密为16进制,也可以加密成base64/字节数组
            public static String encrypt(String text) {
            return sm4.encryptHex(text);
            }


            //解密
            public static String decrypt(String text) {
            return sm4.decryptStr(text);
            }


            public static void main(String[] args) {
            String text = "hello sm4";
            String encryptText = encrypt(text);
            String decryptText = decrypt(encryptText);
            System.out.println(encryptText + "\n" + decryptText);
            }
            }


            我们用的是对称加密,先生成公钥私钥对 SM4


            非对称加密SM2可以生成公私钥对,服务端保存服务端的私钥,客户端保存服务端下发的公钥,这样,客户端就可以用 服务端下发的公钥 进行数据加密,服务端接收到 request的数据密文,用自己的私钥进行解密即可,这样就完成了,客户端加密,服务端解密,注意的是非对称加密解密是耗性能的,涉及到大数运算,想省性能的兄弟,可以处理成类似https的方式,非对称加密获取对称加密的key,数据传输用对称加密,这样性能好,我的是直接采用的对称加密,我们是https的,https天然对数据传输做了保证,唯一的问题就是处理别人F12来看,隐藏混淆对称加密的key,增加难度。


            若是需要服务端加密,客户端解密。最好客户端也生成一套 公钥 和私钥(用一套的话,服务端的私钥会暴露在客户端上,不安全),客户端公钥是服务端保存,客户端的私钥自己保存,就可实现,服务端的响应数据用客户端的公钥进行加密,客户端接收到服务端的响应密文,用自己客户端的私钥解密即可,

            对称加密相对简单,客户端和服务端的加密和解密都用同一个 密钥 key 即可
















            文章转载自IT学习道场,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论