首页 > 编程语言 >国密算法SM4的GCM模式加密解密实现

国密算法SM4的GCM模式加密解密实现

时间:2023-11-30 09:26:48浏览次数:50  
标签:cipherText return String SM4 GCM iv 国密 byte null

import org.bouncycastle.util.encoders.Hex;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SM4Utils {
    /**
     * 默认 SECRET_KEY
     * secretKey 必须为16位,可包含字母、数字、标点
     */
	private static String SECRET_KEY =""
	/**
     * 默认 IV
     * 当时用CBC模式的时候,SECRET_KEY和IV都需要传值,解密要和加密的SECRET_KEY和IV一致,更加安全
     * iv 必须为 16 位,可包含字母、数字、标点
     */
    private static final String IV = "";
    
    private static final Pattern P = Pattern.compile("\\s*|\t|\r|\n");
    /**
     * GCM模式加密,默认密钥
     *
     * @param plainText 要加密的数据
     * @return String
     */
    public static String encryptData_GCM(String plainText) {
        if (plainText == null) {
            return null;
        }
        try {
            SM4 sm4 = new SM4();
            byte[] key;
            byte[] iv;
            byte[] data;

            key = SM4Utils.SECRET_KEY.getBytes();
            iv = SM4Utils.getIv().getBytes();
            data = plainText.getBytes();

            // 加密
            String cipherText = encrypt_crypt_gcm(key, iv, data);
            if (cipherText != null && cipherText.trim().length() > 0) {
                Matcher m = P.matcher(cipherText);
                cipherText = m.replaceAll("");
            }
            return cipherText;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
     /**
     * GCM模式加密, secertKey和iv需要自己传值, 加密解密一致
     * @param plainText plainText
     * @return String
     */
    public static String encryptData_GCM(String plainText, String secretKey, String ivString) {
        if (plainText == null) {
            return null;
        }
        try {
            SM4 sm4 = new SM4();
            byte[] key;
            byte[] iv;
            byte[] data;

            key = secretKey.getBytes();
            iv = ivString.getBytes();
            data = plainText.getBytes();

            // 加密
            String cipherText = encrypt_crypt_gcm(key, iv, data);
            if (cipherText != null && cipherText.trim().length() > 0) {
                Matcher m = P.matcher(cipherText);
                cipherText = m.replaceAll("");
            }
            return cipherText;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static String encrypt_crypt_gcm(byte[] key, byte[] iv, byte[] data) throws Exception {
        if (iv == null || iv.length != 16) {
            throw new Exception("iv error!");
        }

        if (data == null) {
            throw new Exception("input is null!");
        }
        SM4Engine engine = new SM4Engine();
        GCMBlockCipher cipher = new GCMBlockCipher(engine);
        KeyParameter keyParam = new KeyParameter(key);
        AEADParameters params = new AEADParameters(keyParam, 128, iv, null);
        cipher.init(true, params);
        byte[] ciphertext = new byte[cipher.getOutputSize(data.length)];
        int len = cipher.processBytes(data, 0, data.length, ciphertext, 0);
        cipher.doFinal(ciphertext, len);
        return Hex.toHexString(ciphertext);
    }
    
     /**
     * GCM模式解密,SECRET_KEY和IV都需要传值,解密要和加密的SECRET_KEY和IV一致,更加安全
     *
     * @param cipherText String
     * @param secretKey String
     * @param ivString String
     * @return String
     * @author yanXu
     */
    public static String decryptData_GCM(String cipherText, String secretKey, String ivString) {
        if (cipherText == null) {
            return null;
        }
        try {
            byte[] key;
            byte[] iv;
            byte[] data;

            key = secretKey.getBytes();
            iv = ivString.getBytes();
            data = Hex.decode(cipherText);

            return decrypt_crypt_gcm(key, iv, data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * GCM模式解密,SECRET_KEY和IV为默认值
     *
     * @param cipherText String
     * @return String
     * @author yanXu
     */
    public static String decryptData_GCM(String cipherText) {
        if (cipherText == null) {
            return null;
        }
        try {
            byte[] key;
            byte[] iv;
            byte[] data;

            key = SECRET_KEY.getBytes();
            iv = IV.getBytes();
            data = Hex.decode(cipherText);

            return decrypt_crypt_gcm(key, iv, data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static String decrypt_crypt_gcm(byte[] key, byte[] iv, byte[] input) throws Exception {
        if (input == null) {
            throw new Exception("input is null!");
        }
        SM4Engine engine = new SM4Engine();
        GCMBlockCipher cipher = new GCMBlockCipher(engine);
        KeyParameter keyParam = new KeyParameter(key);
        AEADParameters params = new AEADParameters(keyParam, 128, iv, null);

        cipher.init(false, params);
        byte[] decrypted = new byte[cipher.getOutputSize(input.length)];
        int len = cipher.processBytes(input, 0, input.length, decrypted, 0);
        cipher.doFinal(decrypted, len);
        return new String(decrypted);
    }

标签:cipherText,return,String,SM4,GCM,iv,国密,byte,null
From: https://www.cnblogs.com/jiuchenchen/p/17866486.html

相关文章

  • 国密
    国密是指中国的密码学算法标准,全称为“商用密码产业发展与标准化工作组”。国密算法由中国密码技术发展中心(第三研究所)和中国国家商用密码管理办公室组织开发和标准化。国密算法包括对称密码算法、非对称密码算法和密码hash算法。对称密码算法包括SM1、SM2、SM3和SM4;非对称......
  • PHP 国密SM2 私钥公钥计算公式
      在线测试地址1.私钥可查询出公钥;公钥无法计算私钥,注意保护私钥安全;2.分割字符串:PHP函数substr($str,36|76);3.HEX转base64:PHP函数base64_encode(hex2bin());4.base64转HEX:PHP函数bin2hex(base64_decode());5.公钥HEX转PEM证书:字符串'3059301306072a8648ce3d02......
  • 基于Wireshark插件的国密标准检测工具的设计与实现——任务理解与分工
    任务分工:应用和数据部分不可否认性的实现对任务的理解以下是我对任务的理解:任务背景:任务涉及到对用户进行身份验证和签名验证,以确保用户的关键操作行为是合法和安全的。用户1的操作:步骤23:正确给出√×*,这似乎是用户1的关键操作行为的一部分,需要验证其签名的合法性。步骤24......
  • 基于wireshark插件的国密标准检测工具的设计与实现前期安排
    任务理解:  整体任务:写.lua插件,其中创建的协议实现解析抓包数据并完成相关密评标准阶段安排:第一周:理解任务要求,学习相关知识,配置编程环境,分配工作学习笔记https://www.cnblogs.com/dkyzhouyikai/p/17841223.html  第二周:着手实现与检验  第三周:验收成员分工:......
  • 基于wireshark插件的国密标准检测工具的设计与实现
    基于lua语言的wireshark插件开发lua运算符--createanewdissectorlocalNAME="Doip"localPORT=13400localDoip=Proto(NAME,"DoipProtocol")--dissectpacketfunctionDoip.dissector(tvb,pinfo,tree)end--registerthisdissectorDissec......
  • mysql 国密加密字段排序和模糊搜索
    双写加密字段和明文分别存到两个字段中,查询只对明文进行操作. (备注:这种只是应对检查或者设计的方式,对于程序没有实际意义)使用函数利用mysql已有加解密的函数,在排序和模糊搜索之前解密数据,再进行排序或者模糊搜索.(备注:查询速度受到很大影响,不能使......
  • C#.NET 国密SM4 CBC 对称加解密 与JAVA互通 ver:20231103
    C#.NET国密SM4CBC对称加解密与JAVA互通ver:20231103 .NET环境:.NET6控制台程序(.netcore)。JAVA环境:JAVA8,带maven的JAVA控制台程序。 简要解析:1:加密的KEY、明文等输入参数都需要string转byte[],要约定好编码,如:UTF8。2:加密后的输出参数:byte[],在传输时需要转......
  • 国密sm2、sm3、sm4的js使用
    安装:npminstallsm-cryptoOryarnaddsm-cryptosm2:获取密钥对:constsm2=require('sm-crypto').sm2letkeypair=sm2.generateKeyPairHex()publicKey=keypair.publicKey//公钥privateKey=keypair.privateKey//私钥//默认生成公钥130位太长,可以压缩公......
  • 国密sm4算法
    一、概述国密算法定义:即国家密码局认定的国产密码算法。通过定义我们可以知道,国密算法有两个要素:1、国家密码局认定在国家密码局官网上,可以看到由其发布的标准规范。2、密码算法首先知道什么是密码,密码就是将正常的信息加密后变为无法正常识别的编码,可以认为是一种混淆......
  • 基于sm-crypto的sm4的请求加密&响应加密
    有时候需要对项目的请求和返回值进行加密请求,因而笔者使用了sm4,读者也可以使用别的库如md5封装加解密://ciphertext.jsconstsm4=require('sm-crypto').sm4//此为密文key,非常重要exportconstCIPHERTEXT=`wzdxcskwzdxcskwzdxcskwzdxcskwzdxcsk`//我真的想吃烧烤我真的......