sm3与sm4

news/2024/11/29 7:54:28/

介绍:

国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。

1. SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。

2. SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。

3. SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。

4. SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

在金融领域目前主要使用公开的SM2、SM3、SM4三类算法,分别是非对称算法、哈希算法和对称算法

SM2算法:SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,包括SM2-1椭圆曲线数字签名算法,SM2-2椭圆曲线密钥交换协议,SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高。

      SM3算法:SM3杂凑算法是我国自主设计的密码杂凑算法,适用于商用密码应用中的数字签名和验证消息认证码的生成与验证以及随机数的生成,可满足多种密码应用的安全需求。为了保证杂凑算法的安全性,其产生的杂凑值的长度不应太短,例如MD5输出128比特杂凑值,输出长度太短,影响其安全性SHA-1算法的输出长度为160比特,SM3算法的输出长度为256比特,因此SM3算法的安全性要高于MD5算法和SHA-1算法。

     SM4算法:SM4分组密码算法是我国自主设计的分组对称密码算法,用于实现数据的加密/解密运算,以保证数据和信息的机密性。要保证一个对称密码算法的安全性的基本条件是其具备足够的密钥长度,SM4算法与AES算法具有相同的密钥长度分组长度128比特,因此在安全性上高于3DES算法。

demo:

maven:

      <!--  国密算法   --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.65</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.65</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>RELEASE</version><scope>compile</scope></dependency><!--  国密算法   -->

sm3:

SM3Utils:

package com.zzh.ms3;import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.Security;
import java.util.Arrays;public class SM3Utils {static {Security.addProvider(new BouncyCastleProvider());}/*** 计算SM3摘要值** @param srcData 原文* @return 摘要值,对于SM3算法来说是32字节*/public static byte[] hash(byte[] srcData) {SM3Digest digest = new SM3Digest();digest.update(srcData, 0, srcData.length);byte[] hash = new byte[digest.getDigestSize()];digest.doFinal(hash, 0);return hash;}/*** 验证摘要** @param srcData 原文* @param sm3Hash 摘要值* @return 返回true标识验证成功,false标识验证失败*/public static boolean verify(byte[] srcData, byte[] sm3Hash) {byte[] newHash = hash(srcData);return Arrays.equals(newHash, sm3Hash);}/*** 计算SM3 Mac值* @param key     key值,可以是任意长度的字节数组* @param srcData 原文* @return Mac值,对于HMac-SM3来说是32字节*/public static byte[] hmac(byte[] key, byte[] srcData) {KeyParameter keyParameter = new KeyParameter(key);SM3Digest digest = new SM3Digest();HMac mac = new HMac(digest);mac.init(keyParameter);mac.update(srcData, 0, srcData.length);byte[] result = new byte[mac.getMacSize()];mac.doFinal(result, 0);return result;}
}

测试um3:

package com.zzh.ms3;import org.bouncycastle.util.encoders.Base64;
import org.junit.Assert;
import org.junit.Test;import java.nio.charset.StandardCharsets;
import java.util.Arrays;public class SM3UtilsTest {public static final String KEY = "1234567812345678";public static final String CHARSET_UTF8 = StandardCharsets.UTF_8.name();@Testpublic void testGenerateHash() throws Exception {String data = "测试SM3杂凑算法";// 生成消息摘要  消息摘要=SM3(原文)byte[] signByte = SM3Utils.hash(data.getBytes(CHARSET_UTF8));String signBase64String = Base64.toBase64String(signByte);System.out.println("\n消息摘要 Base64 String:" + signBase64String);// 生成数字签名  数字签名 = SM3(原文+密钥)String digitalSign = Base64.toBase64String(SM3Utils.hash((data + KEY).getBytes(CHARSET_UTF8)));System.out.println("\n数字签名 Base64 String:" + digitalSign);}@Testpublic void testHashAndVerify() {try {/*加密*/String data = "SM3UtilsTest";byte[] hash = SM3Utils.hash(data.getBytes(CHARSET_UTF8));System.out.println("hash:" + Arrays.toString(hash));String hashBase64String = Base64.toBase64String(hash);System.out.println("SM3 Base64 String:\n" + hashBase64String);System.out.println("hash:\n" + Arrays.toString(Base64.decode(hashBase64String)));/*校验*/boolean flag = SM3Utils.verify(data.getBytes(CHARSET_UTF8), hash);System.out.println("验证结果:" + flag);System.out.println("======");Assert.assertTrue(flag);} catch (Exception ex) {ex.printStackTrace();}}}

sm4:

SM4Utils:

package com.zzh.ms4;import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
import org.bouncycastle.crypto.macs.GMac;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.paddings.BlockCipherPadding;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;public class SM4Utils {static {Security.addProvider(new BouncyCastleProvider());}public static final String ALGORITHM_NAME = "SM4";public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";/*** SM4算法目前只支持128位(即密钥16字节)*/public static final int DEFAULT_KEY_SIZE = 128;public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {return generateKey(DEFAULT_KEY_SIZE);}public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);kg.init(keySize, new SecureRandom());return kg.generateKey().getEncoded();}public static byte[] encrypt_ECB_Padding(byte[] key, byte[] data)throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data);}public static byte[] decrypt_ECB_Padding(byte[] key, byte[] cipherText)throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);return cipher.doFinal(cipherText);}public static byte[] encrypt_ECB_NoPadding(byte[] key, byte[] data)throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data);}public static byte[] decrypt_ECB_NoPadding(byte[] key, byte[] cipherText)throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.DECRYPT_MODE, key);return cipher.doFinal(cipherText);}public static byte[] encrypt_CBC_Padding(byte[] key, byte[] iv, byte[] data)throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,InvalidAlgorithmParameterException {Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key, iv);return cipher.doFinal(data);}public static byte[] decrypt_CBC_Padding(byte[] key, byte[] iv, byte[] cipherText)throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,InvalidAlgorithmParameterException {Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key, iv);return cipher.doFinal(cipherText);}public static byte[] encrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] data)throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,InvalidAlgorithmParameterException {Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);return cipher.doFinal(data);}public static byte[] decrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] cipherText)throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,InvalidAlgorithmParameterException {Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);return cipher.doFinal(cipherText);}public static byte[] doCMac(byte[] key, byte[] data) throws NoSuchProviderException, NoSuchAlgorithmException,InvalidKeyException {Key keyObj = new SecretKeySpec(key, ALGORITHM_NAME);return doMac("SM4-CMAC", keyObj, data);}public static byte[] doGMac(byte[] key, byte[] iv, int tagLength, byte[] data) {org.bouncycastle.crypto.Mac mac = new GMac(new GCMBlockCipher(new SM4Engine()), tagLength * 8);return doMac(mac, key, iv, data);}/*** 默认使用PKCS7Padding/PKCS5Padding填充的CBCMAC** @param key* @param iv* @param data* @return*/public static byte[] doCBCMac(byte[] key, byte[] iv, byte[] data) {SM4Engine engine = new SM4Engine();org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, new PKCS7Padding());return doMac(mac, key, iv, data);}/*** @param key* @param iv* @param padding 可以传null,传null表示NoPadding,由调用方保证数据必须是BlockSize的整数倍* @param data* @return* @throws Exception*/public static byte[] doCBCMac(byte[] key, byte[] iv, BlockCipherPadding padding, byte[] data) throws Exception {SM4Engine engine = new SM4Engine();if (padding == null) {if (data.length % engine.getBlockSize() != 0) {throw new Exception("if no padding, data length must be multiple of SM4 BlockSize");}}org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, padding);return doMac(mac, key, iv, data);}private static byte[] doMac(org.bouncycastle.crypto.Mac mac, byte[] key, byte[] iv, byte[] data) {CipherParameters cipherParameters = new KeyParameter(key);mac.init(new ParametersWithIV(cipherParameters, iv));mac.update(data, 0, data.length);byte[] result = new byte[mac.getMacSize()];mac.doFinal(result, 0);return result;}private static byte[] doMac(String algorithmName, Key key, byte[] data) throws NoSuchProviderException,NoSuchAlgorithmException, InvalidKeyException {Mac mac = Mac.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);mac.init(key);mac.update(data);return mac.doFinal();}private static Cipher generateECBCipher(String algorithmName, int mode, byte[] key)throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,InvalidKeyException {Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);cipher.init(mode, sm4Key);return cipher;}private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,NoSuchProviderException, NoSuchPaddingException {Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);cipher.init(mode, sm4Key, ivParameterSpec);return cipher;}
}

sm4测试:

package com.zzh.ms4;import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.junit.Test;import java.nio.charset.StandardCharsets;public class SM4UtilsTest {@Testpublic void testCustomKeySM4ECB() throws Exception {String charset = StandardCharsets.UTF_8.name();// SM4密钥长度分组长度128bit,因此密匙长度为16String myKey = "zhangzhangzhangz";String data = "SM4UtilsTest";byte[] myKeyBytes = myKey.getBytes(charset);byte[] encryptedBytes = SM4Utils.encrypt_ECB_Padding(myKeyBytes, data.getBytes(charset));String encryptedHexString = ByteUtils.toHexString(encryptedBytes);System.out.println("ECB加密后的数据HexString:" + encryptedHexString);byte[] decryptedBytes = SM4Utils.decrypt_ECB_Padding(myKeyBytes, ByteUtils.fromHexString(encryptedHexString));System.out.println("ECB解密后的数据:" + new String(decryptedBytes, charset));}@Testpublic void testCustomKeySM4CBC() throws Exception {String charset = StandardCharsets.UTF_8.name();// SM4密钥长度分组长度128bit,因此密匙长度为16String myKey = "1234567812345678";String myIv = "8765432187654321";String data = "SM4UtilsTest";byte[] myKeyBytes = myKey.getBytes(charset);byte[] myIvBytes = myIv.getBytes(charset);byte[] encryptedBytes = SM4Utils.encrypt_CBC_Padding(myKeyBytes, myIvBytes, data.getBytes(charset));String encryptedHexString = ByteUtils.toHexString(encryptedBytes);System.out.println("CBC加密后的数据HexString:" + encryptedHexString);byte[] decryptedBytes = SM4Utils.decrypt_CBC_Padding(myKeyBytes, myIvBytes, ByteUtils.fromHexString(encryptedHexString));System.out.println("CBC解密后的数据:" + new String(decryptedBytes, charset));}}


http://www.ppmy.cn/news/243770.html

相关文章

卡奥斯开源社区六月创作之星挑战赛开始啦!

活动须知 发布优质文章争榜&#xff0c;获取专属勋章、流量扶持及奖励&#xff01; 活动时间&#xff1a;6 月 1 日- 6 月 30 日 奖品发放&#xff1a;7月10日 参与方式 完成认证发布优质文章&#xff0c;选中相关活动标签&#xff0c;文章默认参与活动 文章要求 文章符合…

okta/sf平台实现saml2.0单点登录集成实战(详细步骤+完整代码)

目录 第一步&#xff1a;注册okta账号 第二步&#xff1a;配置okta应用信息 第三步&#xff1a;下载Idp.xml文件 第四步&#xff1a;okta特定配置 第五步&#xff1a;集成测试 基于SuccessFactors的单点登录实现 Github工程代码链接 小结 笔者以前写过一篇关于saml2.0单…

【无标题】-自用

rad表示弧度radian&#xff0c;deg表示角度degree&#xff1b; 1. 用基于轮廓的模版匹配&#xff0c;匹配到之后&#xff0c;会有一个参数输出目标与原模版相比旋转的角度。 2. 原图的左上角点和右下角点连线&#xff0c;再把旋转之后图的上角与下角连线&#xff0c;测量两条线…

使用mongo遇到一些需要查询的符合要求的数据,写sql

1.修改符合条件的数据 如果一个值在A数组中存在,那么修改该数据中B数组,只保留B数组中xxx db.user.find({account:"csbj"}).pretty() {"_id" : ObjectId("6139680bde8bcd0001beb194"),"id" : 813,"account" : "csb…

ubuntu

#关于win10下linux的启动记录; 惠普&#xff08;暗影精灵&#xff09;BIOS里BOOT Option 里选择OS BOOT manager &#xff0c;Enter键选择windows或者ubuntu的启动顺序&#xff0c;将ubuntu设为第一&#xff0c;F10保存即可在启动后&#xff0c;提供windows或者ubuntu的系统选项…

硬盘坏了

1.今天打开电脑(联想E49),系统无法启动&#xff0c;一直显示的是如下图界面&#xff0c;我以为系统坏了&#xff0c;然后打算重装系统&#xff0c; 用的是老毛桃装机软件 2.用老毛桃U盘引导后&#xff0c;然而在磁盘树上却找不到硬盘&#xff0c;只显示了我的 U 盘&#xff0c…

ESXI6.7下直通硬盘给群晖步骤,RDM直通方式

1.进入ESXI6.7 web管理后台。开启SSH 2.点击存储&#xff0c;选择默认存储(ESXI安装硬盘)。复制位置地址备用 3.打开SSH工具&#xff0c;登录SSH。登录以后执行以下命令。 执行命令1&#xff1a; cd /vmfs/volumes/5fb14c74-5da1723a-c6a0-00e15a680bd8 /vmfs/volumes/5fb14…

intel安装mac os

一、变色龙&#xff1a; 1.http://bbs.pcbeta.com/forum.php?modviewthread&tid1518901&extrapage%3D1%26orderby%3Dheats&page1 如何安装kext&如何修改org.chameleon.boot.plist和smbios.plist&#xff1a;http://bbs.pcbeta.com/viewthread-936953-1-1.html…