国密sm4加密算法

国密sm4加密算法国密sm4加解密算法工具类,可用于生产环境packagecom.example.demo.endecryption.utils;importorg.apache.commons.codec.binary.Base64;importorg.bouncycastle.jce.provider.BouncyCastleProvider;importjavax.crypto.BadPa…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

国密sm4加解密算法工具类,可用于生产环境
package com.example.demo.endecryption.utils;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.Security;

/** * 国密sm4加解密 */
public class Sm4Util { 
   
    public enum Algorithm { 
   

        SM4("SM4","SM4","key长度:16 byte");

        private String keyAlgorithm;
        private String transformation;
        private String description;//描述
        Algorithm(String keyAlgorithm, String transformation, String description) { 
   
            this.keyAlgorithm = keyAlgorithm;
            this.transformation = transformation;
            this.description = description;
        }
        public String getKeyAlgorithm() { 
   
            return this.keyAlgorithm;
        }
        public String getTransformation() { 
   
            return this.transformation;
        }
        public String getDescription() { 
   
            return this.description;
        }
    }

    private static final String PROVIDER_NAME = "BC";//BouncyCastleProvider的名字
    static { 
   
        Security.addProvider(new BouncyCastleProvider());
    }


    /** * 自定字符串产生密钥 * @param algorithm 加解密算法 * @param keyStr 密钥字符串 * @param charset 编码字符集 * @return 密钥 */
    public static SecretKey genKeyByStr(Algorithm algorithm, String keyStr, Charset charset) { 
   
        return readKeyFromBytes(algorithm, keyStr.getBytes(charset));
    }

    /** * 根据指定字节数组产生密钥 * @param algorithm 加解密算法 * @param keyBytes 密钥字节数组 * @return 密钥 */
    public static SecretKey readKeyFromBytes(Sm4Util.Algorithm algorithm, byte[] keyBytes) { 
   
        return new SecretKeySpec(keyBytes, algorithm.getKeyAlgorithm());
    }

    /****************************加密*********************************/
    /** * 加密字符串,并进行base64编码 * @param algorithm 加解密算法 * @param key 密钥 * @param data 明文 * @param charset 编码字符集 * @return 密文 * @throws InvalidKeyException 密钥错误 */
    public static String encryptBase64(Sm4Util.Algorithm algorithm, SecretKey key, String data, Charset charset) throws InvalidKeyException { 
   
        return Base64.encodeBase64String(encrypt(algorithm, key, data.getBytes(charset)));
    }

    /** * 加密字节数组 * @param algorithm 加解密算法 * @param key 密钥 * @param data 明文 * @return 密文 * @throws InvalidKeyException 密钥错误 */
    public static byte[] encrypt(Sm4Util.Algorithm algorithm, SecretKey key, byte[] data) throws InvalidKeyException { 
   
        try { 
   
            return cipherDoFinal(algorithm, Cipher.ENCRYPT_MODE, key, data);
        } catch (BadPaddingException e) { 
   
            throw new RuntimeException(e);//明文没有具体格式要求,不会出错。所以这个异常不需要外部捕获。
        }
    }

    /** * 加解密字节数组 * @param algorithm 加解密算法 * @param opmode 操作:1加密,2解密 * @param key 密钥 * @param data 数据 * @throws InvalidKeyException 密钥错误 * @throws BadPaddingException 解密密文错误(加密模式没有) */
    private static byte[] cipherDoFinal(Sm4Util.Algorithm algorithm, int opmode, SecretKey key, byte[] data) throws InvalidKeyException, BadPaddingException { 
   
        Cipher cipher;
        try { 
   
            cipher = Cipher.getInstance(algorithm.getTransformation(), PROVIDER_NAME);
        } catch (Exception e) { 
   
            //NoSuchAlgorithmException:加密算法名是本工具类提供的,如果错了业务没有办法处理。所以这个异常不需要外部捕获。
            //NoSuchProviderException:Provider是本工具类提供的,如果错了业务没有办法处理。所以这个异常不需要外部捕获。
            //NoSuchPaddingException:没有特定的填充机制,与环境有关,业务没有办法处理。所以这个异常不需要外部捕获。
            throw new RuntimeException(e);
        }
        cipher.init(opmode, key);
        try { 
   
            return cipher.doFinal(data);
        } catch (IllegalBlockSizeException e) { 
   
            throw new RuntimeException(e);//业务不需要将数据分块(好像由底层处理了),如果错了业务没有办法处理。所以这个异常不需要外部捕获。
        }
    }

    /****************************解密*********************************/
    /** * 对字符串先进行base64解码,再解密 * @param algorithm 加解密算法 * @param key 密钥 * @param data 密文 * @param charset 编码字符集 * @return 明文 * @throws InvalidKeyException 密钥错误 * @throws BadPaddingException 密文错误 */
    public static String decryptBase64(Sm4Util.Algorithm algorithm, SecretKey key, String data, Charset charset)
            throws InvalidKeyException, BadPaddingException { 
   
        return new String(decrypt(algorithm, key, Base64.decodeBase64(data)), charset);
    }

    /** * 解密字节数组 * @param algorithm 加解密算法 * @param key 密钥 * @param data 密文 * @return 明文 * @throws InvalidKeyException 密钥错误 * @throws BadPaddingException 密文错误 */
    public static byte[] decrypt(Sm4Util.Algorithm algorithm, SecretKey key, byte[] data) throws InvalidKeyException, BadPaddingException { 
   
        return cipherDoFinal(algorithm, Cipher.DECRYPT_MODE, key, data);
    }
}

测试
 /** * 国密sm4加解密 */
 @Test
 public void sm4Test() throws InvalidKeyException, BadPaddingException { 
   
     Sm4Util .Algorithm algorithm = SymEncUtil.Algorithm.SM4;
     //16位密钥字符串
     String encryptKey = "0123456789ABCDEF";
     //编码格式
     Charset encryptCharset = StandardCharsets.UTF_8;
     //生产密钥
     SecretKey key = Sm4Util .genKeyByStr(algorithm, encryptKey, encryptCharset);
     //加密
     String encryptBase64 = Sm4Util .encryptBase64(algorithm, key, "123456", encryptCharset);
     System.out.println("encryptBase64 = " + encryptBase64);//encryptBase64=QtrH8m/aR9x/cySEoUb+Nw==
     //解密
     String decryptBase64 = Sm4Util .decryptBase64(algorithm, key, "QtrH8m/aR9x/cySEoUb+Nw==", encryptCharset);
     System.out.println("decryptBase64 = " + decryptBase64);
 }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185499.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab批量处理excel(CSV)文件数据

    matlab批量处理excel(CSV)文件数据今天是2019-1-29,参加完2019年美国大学生数学建模竞赛,小伙伴都回家了,就我一个人在寝室,太无聊了,就把在比赛中遇到的excel批处理,写一下思路(ps:其实我在比赛中利用的是SQLServer数据库和matlab相结合的数据处理方法,但是一般情况下遇到的都是matlab对excel数据批处理,所以降低要求写了matlab对exc…

    2022年6月28日
    26
  • Android面试题大全(中高级)

    Android面试题大全(中高级)1.synchronized和lock的区别答:https://blog.csdn.net/u012403290/article/details/64910926?locationNum=11&fps=1还可以去了解什么是可重入锁,公平锁,可中断锁。2.okhttp源码分析答:https://blog.csdn.net/mwq384807683/article…

    2022年5月22日
    24
  • Extjs grid设置单元格字体颜色,及单元格背景色

    Extjs grid设置单元格字体颜色,及单元格背景色转自:http://blog.csdn.net/suixufeng/article/details/7480170上面这种是最简单的,设定固定的某单元格中字体颜色。[javascript]viewplaincopy//————————————————–列头    var cm = new

    2022年7月11日
    88
  • 监督学习、无监督学习、自监督学习和强化学习

    监督学习、无监督学习、自监督学习和强化学习监督学习监督学习是目前最常见的机器学习类型。给定一组样本(通常由人工标注),他可以学会将输入数据映射到已知目标。一般来说,近年来过度关注的深度学习应用几乎都属于监督学习,比如光学字符识别、语音识别、图像分类和语言翻译。监督学习主要包括分类和回归,但还有更多的奇特变体,主要包括如下几种:1、序列生成(sequencegeneration)。给定一张图像,预测描述图像的文字。序列生成有时可…

    2025年11月15日
    4
  • 黄页网址大全推荐_常用的网站

    黄页网址大全推荐_常用的网站可以试试这个,https://tongcheng360.com页面干净整洁,页面使用缓存技术,打开速度非常快,包括公司简介,发布公司产品,发布公司新闻,公司如有特殊需求,可进行定制化开发,大大节省了公司的运维和开发成本并且具有同城分类信息的功能b站操作视频https://www.bilibili.com/video/BV1jy4y1L7Z1…

    2022年5月3日
    259
  • java中的多行注释快捷键_eclipse多行注释快捷键「建议收藏」

    java中的多行注释快捷键_eclipse多行注释快捷键「建议收藏」eclipse为多行添加注释是有快捷方式可用的,了解了这个快捷方式相信很多网友都会大大提高编码效率,其实同时为多行添加注释可以分别添加“/**/”和“//”样式的,样式不同快捷键也会不同,下面我们可以一起看看具体的添加注释方法。eclipse多行注释快捷键方法一、使用Ctrl+Shift+C快捷键1、在Eclipse中拖动鼠标,选中需要注释的代码。2、按住Ctrl+Shift+C快捷键,如图所示…

    2022年8月15日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号