SM4 国密算法_sm4/ecb/pkcs5padding_zhglhy的博客-程序员宅基地

技术标签: java  网络  网络协议  p2p  

public class Sm4 {


    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String ENCODING = "UTF-8";
    public static final String ALGORITHM_NAME = "SM4";
    // 加密算法/分组加密模式/分组填充方式
    // PKCS5Padding-以8个字节为一组进行分组加密
    // 定义分组加密模式使用:PKCS5Padding
    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
    // 128-32位16进制;256-64位16进制
    public static final int DEFAULT_KEY_SIZE = 128;

    /**
     * 自动生成密钥
     *
     * @return
     * @explain
     */
    public static String generateKey() throws Exception {
        return new String(Hex.encodeHex(generateKey(DEFAULT_KEY_SIZE),false));
    }

    /**
     * @param keySize
     * @return
     * @throws Exception
     * @explain
     */
    public static byte[] generateKey(int keySize) throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
        kg.init(keySize, new SecureRandom());
        return kg.generateKey().getEncoded();
    }

    /**
     * 生成ECB暗号
     *
     * @param algorithmName 算法名称
     * @param mode          模式
     * @param key
     * @return
     * @throws Exception
     * @explain ECB模式(电子密码本模式:Electronic codebook)
     */
    private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
        Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
        cipher.init(mode, sm4Key);
        return cipher;
    }

    /**
     * sm4加密
     *
     * @param hexKey   16进制密钥(忽略大小写)
     * @param paramStr 待加密字符串
     * @return 返回16进制的加密字符串
     * @explain 加密模式:ECB
     * 密文长度不固定,会随着被加密字符串长度的变化而变化
     */
    public static String encryptEcb(String hexKey, String paramStr) {
        try {
            String cipherText = "";
            // 16进制字符串-->byte[]
            byte[] keyData = ByteUtils.fromHexString(hexKey);
            // String-->byte[]
            byte[] srcData = paramStr.getBytes(ENCODING);
            // 加密后的数组
            byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);
            // byte[]-->hexString
            cipherText = ByteUtils.toHexString(cipherArray);
            return cipherText;
        } catch (Exception e) {
            return paramStr;
        }
    }

    /**
     * 加密模式之Ecb
     *
     * @param key
     * @param data
     * @return
     * @throws Exception
     * @explain
     */
    public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    /**
     * sm4解密
     *
     * @param hexKey     16进制密钥
     * @param cipherText 16进制的加密字符串(忽略大小写)
     * @return 解密后的字符串
     * @throws Exception
     * @explain 解密模式:采用ECB
     */
    public static String decryptEcb(String hexKey, String cipherText) {
        // 用于接收解密后的字符串
        String decryptStr = "";
        // hexString-->byte[]
        byte[] keyData = ByteUtils.fromHexString(hexKey);
        // hexString-->byte[]
        byte[] cipherData = ByteUtils.fromHexString(cipherText);
        // 解密
        byte[] srcData = new byte[0];
        try {
            srcData = decrypt_Ecb_Padding(keyData, cipherData);
            // byte[]-->String
            decryptStr = new String(srcData, ENCODING);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptStr;
    }

    /**
     * 解密
     *
     * @param key
     * @param cipherText
     * @return
     * @throws Exception
     * @explain
     */
    public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

    /**
     * 校验加密前后的字符串是否为同一数据
     *
     * @param hexKey     16进制密钥(忽略大小写)
     * @param cipherText 16进制加密后的字符串
     * @param paramStr   加密前的字符串
     * @return 是否为同一数据
     * @throws Exception
     * @explain
     */
    public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception {
        // 用于接收校验结果
        boolean flag = false;
        // hexString-->byte[]
        byte[] keyData = ByteUtils.fromHexString(hexKey);
        // 将16进制字符串转换成数组
        byte[] cipherData = ByteUtils.fromHexString(cipherText);
        // 解密
        byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData);
        // 将原字符串转换成byte[]
        byte[] srcData = paramStr.getBytes(ENCODING);
        // 判断2个数组是否一致
        flag = Arrays.equals(decryptData, srcData);
        return flag;
    }


    public static void main(String[] args) {

        String key = "74d32aad624c62be6f774648530af79e";

        String cipher = "hello world";

        try {

            String enStr = Sm4Util.encryptEcb(key, cipher);
            System.out.println(enStr);

            String json = Sm4Util.decryptEcb(key, enStr);
            System.out.println(json);


        } catch (Exception exception) {
            exception.printStackTrace();
        }

    }


}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhglhy/article/details/122961968

智能推荐

梯度下降算法动图_梯度下降算法原理及代码实现-程序员宅基地

1概述梯度下降(Gradient Descent)在机器学习中是很常用的算法,它不仅被用在了线性回归上,还被广泛应用于机器学习的众多领域,它的主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。本文将从一个下山的场景开始,先提出梯度下降算法的基本思想,进而从数学上解释梯度下降算法的原理,解释为什么要用梯度,最后将此算法应用于具体的拟合直线的线性回归中。2 梯度下降算法2.1场景假设想象一..._梯度下降动态图怎么做

Java中获取数组长度_java数组长度_普通网友的博客-程序员宅基地

Java中获取数组长度方法:使用数组属性length来获取数组长度代码:public class ArrayLength { public static void main(String[] args) { String[][] data = new String[2][5]; System.out.println("第一维数组的长度:"+data.length); System.out.println("第二维数组的长度:"+data[0].length); }}结果:_java数组长度

mugen linux主程序,mugen主程序win版下载-程序员宅基地

M.U.G.E.N是一款非常有名的格斗游戏引擎,通过从fighter factory制作的人物模型最终就是在MUGEN之中运行,很多游戏都是基于M.U.G.E.N制作,比如拳皇WING、死神VS火影、东东的不死传说...软件还支持各种不同的游戏人物格斗对战,是一款简易的格斗游戏制作软件。基本简介M.U.G.E.N是一款由美国的Elecbyte小组使用c语言与Allegro程序库开发的免费的2d格斗..._mugen主程序下载

跨模态检索论文阅读:Context-Aware Attention Network for Image-Text Retrieval-程序员宅基地

图像-文本双向检索在很大程度上依赖于每个图像-文本对的联合嵌入学习和相似性度量。先前的工作很少同时探索模态之间的语义对应和单一模态的语义关联。在这项工作中,我们提出了一个统一的上下文感知注意力网络工作(CAAN),它通过聚合全局上下文有选择地关注关键的局部片段(区域和单词)。具体来说,它同时利用全局模态间的对齐和模态内的关联来发现潜在的语义关系。考虑到检索过程中图像和句子之间的相互作用,模内关联来自于对区域-词排列的二阶关注,而不是直观地比较原始特征之间的距离。_跨模态检索

(五)WinXP+IIS6 配置DiscuzNT3.9.913论坛完全手册------常见问题-程序员宅基地

常见问题5.1进行到【3.5】的时候出现以下样子(图见附录1.1),所有安装步骤都出现在一页中,无法完成操作解释:因为dotnetfx4.0(.NET4.0框架)没有安装,安装后重启电脑,再进行访问 5.2 访问权限不够解释:1打开【我的电脑】>>>【工具】>>>【文件夹选项】>>>【查看】,找到【使用简单文件共享(推荐)】,去掉前面的勾,然后确定 2.在虚拟目

随便推点

谈:博客的第一天,RF职场小白进化之路-程序员宅基地

谈:博客的第一天,RF职场小白进化之路啊啊啊啊啊啊,之前一直想利用Hexo和GitHib搭建一个自己的Blog,想装装X,请教了室友还买来一个域名,无奈还是自己太懒了,执行力太差,觉得搭建域名和服务器太麻烦了,毕竟是搞硬件的,对于代码还是觉得头痛。于是,在毕业后刚入职的第二周决定用MD来写Blog,希望我能够对每天学到的东西以及遇到的一些问题进行总结,算作做笔记的一种方式吧。写博客主要是让自己看...

labview快捷操作整理_labview快速连线-程序员宅基地

1.单机、双击、三击连线,可以选择一段,两段和所有连线,按DEl键,则可以删除连线。2.快捷菜单选择“整理连线”项可以自动调整连线。_labview快速连线

数字电子技术基础(四):门电路(TTL)_ttl异或门-程序员宅基地

TTL门电路主要是由三极管构成三极管分为PNP型和NPN型三极管特性和二极管特性相似,因为都是由PN结构成1、三极管反相器2、TTL反相器3、TTL与非门4、TTL或非门5、TTL异或门6、集电极开漏输出的门电路(OC门)在符号上,OC门与OD门相似OC门也可以设计线与逻辑7、三态输出门电路(TS门)由符号可以看出,前者是EN高电平有效,EN为低电平输出高阻态;后者是EN低电平有效,EN为高电平输出高阻态。应用与CMOS的三态门相似注:以上图片均截取自《数字电子_ttl异或门

mybatis使用oracle和mysql批量插入、更新-程序员宅基地

MyBatis foreach语句批量插入数据MyBatis的mapper配置文件的语句(在Oracle数据中,多条数据之间用union all 连接,MySQL数据库用,): <insert id="submitItem" parameterType="java.util.List"> insert into ITEM ( ITEM_COD...

Mixed Content: The page at ‘https://XXX’ was loaded over HTTPS, but requested an in..._https xxx-程序员宅基地

错误:Mixed Content: The page at ‘https://XXX’ was loaded over HTTPS, but requested an in…https总是跳转http讲解。在使用tomcat+nginx时。Nginx使用https,tomcat使用http。使用iframe之类框架,在重定向时会出现以上问题导致页面加载不出来。这是因为Tomcat不能知道Ngi..._https xxx

博弈类题目小结-程序员宅基地

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove首先当然要献上一些非常好的学习资料:基础博弈的小结:http://blog.csdn.net/acm_cxlove/article/details/7854530经典翻硬币游戏小结:http://blog.csd