java国密 C#国密 golang国密 NodeJS国密汇总(三)


2023/05/02更新说明

1、修复明文中包含中文或者标点符号等特殊字符时,摘要计算结果不一致的问题,修复方法是先加明文做base64处理,因为base64的结果都是一致的。具体看下方注释和新增代码。


前言

  不知不觉已经2023年了,最近工作比较忙,各种问题和项目改造,这篇博客就一直拖延到现在,希望各位读者见谅。
  闲话就说到这,让我们一起回顾下之前两期的内容,第一期博主主要演示了java、C#、nodejs、golang4种开发语言的sm2密钥对生成的代码,传送门:java国密 C#国密 golang国密 NodeJS国密汇总(一),第二期博主主要演示了java、C#、nodejs、golang4种开发语言的sm2加签验签、加密解密的代码,传送门:java国密 C#国密 golang国密 NodeJS国密汇总(二)。回顾完后博主就开始本期的内容演示,本期主要把四种开发语言的SM3杂凑算法整上,希望对各位观众大佬有所帮助。


4、SM3计算摘要

由于sm3比较简单,所以这边也不做过多篇幅说明,~~**但是中文需要转码才可以,并且对特殊字符无法处理 **,这两个注意点在演示代码中的注释里有说明。

(1)java

代码示例(中文或者特殊字符遗留问题已解决):

package sm3;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.util.encoders.Hex;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @Author: 系统异常
 * @CreateTime: 2022/12/26 14:45
 * @Description: sm3测试类
 * @Version: 1.0
 */
public class SM3Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        // 定义数组
        byte[] sm3Byte = new byte[32];
        // 初始化sm3
        SM3Digest sm3 = new SM3Digest();

        // 待摘要字符串、数字
        String unSm3Str = "12345678";

        sm3.update(unSm3Str.getBytes(StandardCharsets.UTF_8), 0, unSm3Str.length());
        sm3.doFinal(sm3Byte, 0);

        String sm3StrHex = new String(Hex.encode(sm3Byte));
        System.out.println("java sm3StrHex 数字     -->" + sm3StrHex);

        // 待摘要字符串、字母
        unSm3Str = "abcdefg";

        sm3.update(unSm3Str.getBytes(StandardCharsets.UTF_8), 0, unSm3Str.length());
        sm3.doFinal(sm3Byte, 0);

        sm3StrHex = new String(Hex.encode(sm3Byte));
        System.out.println("java sm3StrHex 字母     -->" + sm3StrHex);
        
		// 2023/05/02 修复明文中包含中文或者标点符号等特殊字符时,摘要计算结果不一致的问题,修复方法是先加明文做base64处理,因为base64的结果都是一致的。
		// 待摘要字符串、中文
        unSm3Str = "你好,世界";
        String changeCodeStr = Base64.toBase64String(unSm3Str.getBytes(StandardCharsets.UTF_8));
        System.out.println("java 中文base64后       -->" + changeCodeStr);

        sm3.update(changeCodeStr.getBytes(StandardCharsets.UTF_8), 0, changeCodeStr.length());
        sm3.doFinal(sm3Byte, 0);

        sm3StrHex = new String(Hex.encode(sm3Byte));
        System.out.println("java sm3StrHex 中文     -->" + sm3StrHex);

        // 特殊字符、
        unSm3Str = ",./;'<>?:\"!@#$%^&*()_+-=`";
        changeCodeStr = Base64.toBase64String(unSm3Str.getBytes(StandardCharsets.UTF_8));
        System.out.println("java 特殊字符base64后   -->" + changeCodeStr);

        sm3.update(changeCodeStr.getBytes(StandardCharsets.UTF_8), 0, changeCodeStr.length());
        sm3.doFinal(sm3Byte, 0);

        sm3StrHex = new String(Hex.encode(sm3Byte));
        System.out.println("java sm3StrHex 特殊字符 -->" + sm3StrHex);
    }
}

演示结果(各种语言的结果中特殊字符不一致、暂未解决,其他情况均测试一致 ):

java sm3StrHex 数字     -->0fffff81e971fa3f09107abf77931463fc0710bfb8962efeae3d5654b073bb0c
java sm3StrHex 字母     -->08b7ee8f741bfb63907fcd0029ae3fd6403e6927b50ed9f04665b22eab81e9b7
java 中文base64后       -->5L2g5aW977yM5LiW55WM
java sm3StrHex 中文     -->3d22faa1b58113903211b22bfd7c119f9b70d9993abb8239ac382b41a315ce3a
java 特殊字符base64后   -->LC4vOyc8Pj86IiFAIyQlXiYqKClfKy09YA==
java sm3StrHex 特殊字符 -->95cbbf02e028fbe9e4514e60c321a0329559e60c2e1b6ddc52124706b2147e90

(2)c#

代码示例(中文或者特殊字符遗留问题已解决):

using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// 九二战歌
/// sm3摘要计算演示
/// </summary>
namespace sm
{
    class Sm3Test
    {
        public void Sm3Calculate()
        {
            // 定义数组
            byte[] sm3Byte = new byte[32];
            // 初始化sm3
            SM3Digest sm3 = new SM3Digest();
            
            // 待摘要字符串、数字
            string unSm3Str = "12345678";
            
            sm3.BlockUpdate(Encoding.UTF8.GetBytes(unSm3Str), 0, unSm3Str.Length);
            sm3.DoFinal(sm3Byte, 0);

            String sm3StrHex = new String(Hex.ToHexString(sm3Byte));
            Console.WriteLine("csharp sm3StrHex 数字     -->" + sm3StrHex);

            // 待摘要字符串、字母
            unSm3Str = "abcdefg";

            sm3.BlockUpdate(Encoding.UTF8.GetBytes(unSm3Str), 0, unSm3Str.Length);
            sm3.DoFinal(sm3Byte, 0);

            sm3StrHex = new String(Hex.ToHexString(sm3Byte));
            Console.WriteLine("csharp sm3StrHex 字母     -->" + sm3StrHex);

			// 2023/05/02 修复明文中包含中文或者标点符号等特殊字符时,摘要计算结果不一致的问题,修复方法是先加明文做base64处理,因为base64的结果都是一致的。
            // 待摘要字符串、中文
            unSm3Str = "你好,世界";
            String changeCodeStr = Base64.ToBase64String(Encoding.UTF8.GetBytes(unSm3Str));
            Console.WriteLine("csharp 中文base64后       -->" + changeCodeStr);

            sm3.BlockUpdate(Encoding.UTF8.GetBytes(changeCodeStr), 0, changeCodeStr.Length);
            sm3.DoFinal(sm3Byte, 0);

            sm3StrHex = new String(Hex.ToHexString(sm3Byte));
            Console.WriteLine("csharp sm3StrHex 中文     -->" + sm3StrHex);

            // 待摘要字符串、特殊字符
            unSm3Str = ",./;'<>?:\"!@#$%^&*()_+-=`";
            changeCodeStr = Base64.ToBase64String(Encoding.UTF8.GetBytes(unSm3Str));
            Console.WriteLine("csharp 特殊字符base64后   -->" + changeCodeStr);

            sm3.BlockUpdate(Encoding.UTF8.GetBytes(changeCodeStr), 0, changeCodeStr.Length);
            sm3.DoFinal(sm3Byte, 0);

            sm3StrHex = new String(Hex.ToHexString(sm3Byte));
            Console.WriteLine("csharp sm3StrHex 特殊字符 -->" + sm3StrHex);
        }
    }
}

演示结果(各种语言的结果中特殊字符不一致、暂未解决,其他情况均测试一致 ):

csharp sm3StrHex 数字     -->0fffff81e971fa3f09107abf77931463fc0710bfb8962efeae3d5654b073bb0c
csharp sm3StrHex 字母     -->08b7ee8f741bfb63907fcd0029ae3fd6403e6927b50ed9f04665b22eab81e9b7
csharp 中文base64后       -->5L2g5aW977yM5LiW55WM
csharp sm3StrHex 中文     -->3d22faa1b58113903211b22bfd7c119f9b70d9993abb8239ac382b41a315ce3a
csharp 特殊字符base64后   -->LC4vOyc8Pj86IiFAIyQlXiYqKClfKy09YA==
csharp sm3StrHex 特殊字符 -->95cbbf02e028fbe9e4514e60c321a0329559e60c2e1b6ddc52124706b2147e90

(3)nodejs

代码示例:

const sm3 = require('sm-crypto').sm3;

function sm3Test() {
    // 待摘要字符串、数字
    let unSm3Str = "12345678";
    let sm3StrHex = sm3(unSm3Str);
    console.log("nodejs sm3StrHex 数字     -->" + sm3StrHex);

    // 待摘要字符串、字母
    unSm3Str = "abcdefg";
    sm3StrHex = sm3(unSm3Str);
    console.log("nodejs sm3StrHex 字母     -->" + sm3StrHex);

	// 2023/05/02 修复明文中包含中文或者标点符号等特殊字符时,摘要计算结果不一致的问题,修复方法是先加明文做base64处理,因为base64的结果都是一致的。
    // 待摘要字符串、中文
    unSm3Str = "你好,世界";
    let changeCodeStr = Buffer.from(unSm3Str).toString('base64');
    console.log("nodejs 中文base64后       -->" + changeCodeStr);
    sm3StrHex = sm3(changeCodeStr);
    console.log("nodejs sm3StrHex 中文     -->" + sm3StrHex);

    // 特殊字符
    unSm3Str = ",./;'<>?:\"!@#$%^&*()_+-=`";
    changeCodeStr = Buffer.from(unSm3Str).toString('base64');
    console.log("nodejs 特殊字符base64后   -->" + changeCodeStr);
    sm3StrHex = sm3(changeCodeStr);
    console.log("nodejs sm3StrHex 特殊字符 -->" + sm3StrHex);
}

sm3Test()

演示结果(各种语言的结果中特殊字符不一致、暂未解决,其他情况均测试一致 ):

nodejs sm3StrHex 数字     -->0fffff81e971fa3f09107abf77931463fc0710bfb8962efeae3d5654b073bb0c
nodejs sm3StrHex 字母     -->08b7ee8f741bfb63907fcd0029ae3fd6403e6927b50ed9f04665b22eab81e9b7
nodejs 中文base64后       -->5L2g5aW977yM5LiW55WM
nodejs sm3StrHex 中文     -->3d22faa1b58113903211b22bfd7c119f9b70d9993abb8239ac382b41a315ce3a
nodejs 特殊字符base64后   -->LC4vOyc8Pj86IiFAIyQlXiYqKClfKy09YA==
nodejs sm3StrHex 特殊字符 -->95cbbf02e028fbe9e4514e60c321a0329559e60c2e1b6ddc52124706b2147e90

(4)golang

代码示例:

package test

import (
	"encoding/hex"
	"fmt"
	"github.com/tjfoc/gmsm/sm3"
	"net/url"
	"testing"
)

func TestSm3(t *testing.T) {
	// 待摘要字符串、数字
	unsignStr := "12345678"
	sm3Byte := sm3.Sm3Sum([]byte(unsignStr))
	sm3StrHex := hex.EncodeToString(sm3Byte)
	fmt.Println("golang sm3StrHex 数字     -->" + sm3StrHex)

	// 待摘要字符串、字母
	unsignStr = "abcdefg"
	sm3Byte = sm3.Sm3Sum([]byte(unsignStr))
	sm3StrHex = hex.EncodeToString(sm3Byte)
	fmt.Println("golang sm3StrHex 字母     -->", sm3StrHex)

	// 2023/05/02 修复明文中包含中文或者标点符号等特殊字符时,摘要计算结果不一致的问题,修复方法是先加明文做base64处理,因为base64的结果都是一致的。
	// 待摘要字符串、中文
	unsignStr = "你好,世界"
	encodedStr := base64.StdEncoding.EncodeToString([]byte(unsignStr))
	fmt.Println("golang 中文base64后       -->", encodedStr)
	sm3Byte = sm3.Sm3Sum([]byte(encodedStr))
	sm3StrHex = hex.EncodeToString(sm3Byte)
	fmt.Println("golang sm3StrHex 中文     -->", sm3StrHex)

	// 待摘要字符串、特殊字符、
	unsignStr = ",./;'<>?:\"!@#$%^&*()_+-=`"
	encodedStr = base64.StdEncoding.EncodeToString([]byte(unsignStr))
	fmt.Println("golang 特殊字符base64后   -->", encodedStr)
	sm3Byte = sm3.Sm3Sum([]byte(encodedStr))
	sm3StrHex = hex.EncodeToString(sm3Byte)
	fmt.Println("golang sm3StrHex 特殊字符 -->", sm3StrHex)
}

演示结果(各种语言的结果中特殊字符不一致、暂未解决,其他情况均测试一致 ):

golang sm3StrHex 数字     -->0fffff81e971fa3f09107abf77931463fc0710bfb8962efeae3d5654b073bb0c
golang sm3StrHex 字母     -->08b7ee8f741bfb63907fcd0029ae3fd6403e6927b50ed9f04665b22eab81e9b7
golang 中文base64后       -->5L2g5aW977yM5LiW55WM
golang sm3StrHex 中文     -->3d22faa1b58113903211b22bfd7c119f9b70d9993abb8239ac382b41a315ce3a
golang 特殊字符base64后   -->LC4vOyc8Pj86IiFAIyQlXiYqKClfKy09YA==
golang sm3StrHex 特殊字符 -->95cbbf02e028fbe9e4514e60c321a0329559e60c2e1b6ddc52124706b2147e90

总结

以上就是博主对四种语言的SM3杂凑算法的演示,这篇博客拖了很久,其一是最近工作比较忙,其二是特殊字符的问题研究了很久一直找不到有效的解决办法,如果有哪位大佬知道特殊字符的解决方案,可以联系我活着在评论区发表,由衷感谢 ,其二的问题已经在五一节中解决,各位可放心参考,最好是给博主一键三连。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九二战歌

原创不易,尽量不白瓢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值