一、概述

国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。目前主要使用公开的SM2、SM3、SM4三类算法,分别是非对称算法、哈希算法和对称算法。

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

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

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

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

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

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

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

由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。

代码地址:https://github.com/bjlhx15/algorithm-sign.git

工具类

packagecom.github.bjlhx15.security.sm;importorg.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.*;importjava.security.spec.ECGenParameterSpec;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjava.util.Base64;/***@authorlihongxu6

*@version1.0

* @className KeyUtils

* @description TODO

* @date 2021-01-13 23:27*/

public classKeyUtils {/*** 生成国密公私钥对

*

* String[0] 公钥

*

* String[1] 私钥

*

*@return*@throwsException*/

public static String[] generateSmKey() throwsException {

KeyPairGenerator keyPairGenerator= null;

SecureRandom secureRandom= newSecureRandom();

ECGenParameterSpec sm2Spec= new ECGenParameterSpec("sm2p256v1");

keyPairGenerator= KeyPairGenerator.getInstance("EC", newBouncyCastleProvider());

keyPairGenerator.initialize(sm2Spec);

keyPairGenerator.initialize(sm2Spec, secureRandom);

KeyPair keyPair=keyPairGenerator.generateKeyPair();

PrivateKey privateKey=keyPair.getPrivate();

PublicKey publicKey=keyPair.getPublic();

String[] result={newString(Base64.getEncoder().encode(publicKey.getEncoded()))

,newString(Base64.getEncoder().encode(privateKey.getEncoded()))

};returnresult;

}/*** 将Base64转码的公钥串,转化为公钥对象

*

*@parampublicKey

*@return

*/

public staticPublicKey createPublicKey(String publicKey) {

PublicKey publickey= null;try{

X509EncodedKeySpec publicKeySpec= newX509EncodedKeySpec(Base64.getDecoder().decode(publicKey));

KeyFactory keyFactory= KeyFactory.getInstance("EC", newBouncyCastleProvider());

publickey=keyFactory.generatePublic(publicKeySpec);

}catch(Exception e) {

e.printStackTrace();

}returnpublickey;

}/*** 将Base64转码的私钥串,转化为私钥对象

*

*@paramprivateKey

*@return

*/

public staticPrivateKey createPrivateKey(String privateKey) {

PrivateKey publickey= null;try{

PKCS8EncodedKeySpec pkcs8EncodedKeySpec= newPKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));

KeyFactory keyFactory= KeyFactory.getInstance("EC", newBouncyCastleProvider());

publickey=keyFactory.generatePrivate(pkcs8EncodedKeySpec);

}catch(Exception e) {

e.printStackTrace();

}returnpublickey;

}

}

View Code

1.1、SM2

代码:

public classBcSm2Util {static{

Security.addProvider(newBouncyCastleProvider());

}/*** 根据publicKey对原始数据data,使用SM2加密*/

public static byte[] encrypt(byte[] data, PublicKey publicKey) {

ECPublicKeyParameters localECPublicKeyParameters= null;if (publicKey instanceofBCECPublicKey) {

BCECPublicKey localECPublicKey=(BCECPublicKey) publicKey;

ECParameterSpec localECParameterSpec=localECPublicKey.getParameters();

ECDomainParameters localECDomainParameters= newECDomainParameters(localECParameterSpec.getCurve(),

localECParameterSpec.getG(), localECParameterSpec.getN());

localECPublicKeyParameters= newECPublicKeyParameters(localECPublicKey.getQ(), localECDomainParameters);

}

SM2Engine localSM2Engine= newSM2Engine();

localSM2Engine.init(true, new ParametersWithRandom(localECPublicKeyParameters, newSecureRandom()));byte[] arrayOfByte2;try{

arrayOfByte2= localSM2Engine.processBlock(data, 0, data.length);returnarrayOfByte2;

}catch(InvalidCipherTextException e) {

e.printStackTrace();return null;

}

}/*** 根据privateKey对加密数据encodedata,使用SM2解密*/

public static byte[] decrypt(byte[] encodedata, PrivateKey privateKey) {

SM2Engine localSM2Engine= newSM2Engine();

BCECPrivateKey sm2PriK=(BCECPrivateKey) privateKey;

ECParameterSpec localECParameterSpec=sm2PriK.getParameters();

ECDomainParameters localECDomainParameters= newECDomainParameters(localECParameterSpec.getCurve(),

localECParameterSpec.getG(), localECParameterSpec.getN());

ECPrivateKeyParameters localECPrivateKeyParameters= newECPrivateKeyParameters(sm2PriK.getD(),

localECDomainParameters);

localSM2Engine.init(false, localECPrivateKeyParameters);try{byte[] arrayOfByte3 = localSM2Engine.processBlock(encodedata, 0, encodedata.length);returnarrayOfByte3;

}catch(InvalidCipherTextException e) {

e.printStackTrace();return null;

}

}/*** 私钥签名*/

public static byte[] signByPrivateKey(byte[] data, PrivateKey privateKey) throwsException {

Signature sig=Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);

sig.initSign(privateKey);

sig.update(data);byte[] ret =sig.sign();returnret;

}/*** 公钥验签*/

public static boolean verifyByPublicKey(byte[] data, PublicKey publicKey, byte[] signature) throwsException {

Signature sig=Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);

sig.initVerify(publicKey);

sig.update(data);boolean ret =sig.verify(signature);returnret;

}

}

测试

public classBcSm2UtilTest {private String test = "woshi测试数据。。..";

java.security.PublicKey publicKey= null;

java.security.PrivateKey privateKey= null;

@Beforepublic void setup() throws Exception {//生成公私钥对

String[] keys =KeyUtils.generateSmKey();

System.out.println("原始数据:" +test);

System.out.println("公钥:" + new String(keys[0]));

System.out.println();

publicKey= KeyUtils.createPublicKey(keys[0]);

System.out.println("私钥:" + new String(keys[1]));

System.out.println();

privateKey= KeyUtils.createPrivateKey(keys[1]);

}

@Testpublic void encrypt() throwsException {byte[] encrypt =BcSm2Util.encrypt(test.getBytes(), publicKey);

String encryptBase64Str=Base64.getEncoder().encodeToString(encrypt);

System.out.println("加密数据:" +encryptBase64Str);byte[] decrypt =BcSm2Util.decrypt(encrypt, privateKey);

System.out.println("解密数据:"+newString(decrypt));byte[] sign =BcSm2Util.signByPrivateKey(test.getBytes(), privateKey);

System.out.println("数据签名:"+Base64.getEncoder().encodeToString(sign));boolean b =BcSm2Util.verifyByPublicKey(test.getBytes(), publicKey,sign);

System.out.println("数据验签:"+b);

}

}

1.2、SM3 hash及hmac

public classBcSm3Util {static{

Security.addProvider(newBouncyCastleProvider());

}public static byte[] sm3(byte[] srcData) {

SM3Digest sm3Digest= newSM3Digest();

sm3Digest.update(srcData,0, srcData.length);byte[] hash = new byte[sm3Digest.getDigestSize()];

sm3Digest.doFinal(hash,0);returnhash;

}public static String sm3Hex(byte[] srcData) {byte[] hash =sm3(srcData);

String hexString=org.apache.commons.codec.binary.Hex.encodeHexString(hash);returnhexString;

}public static byte[] hmacSm3(byte[] key, byte[] srcData) {

KeyParameter keyParameter= newKeyParameter(key);

SM3Digest digest= newSM3Digest();

HMac mac= newHMac(digest);

mac.init(keyParameter);

mac.update(srcData,0, srcData.length);byte[] hash = new byte[mac.getMacSize()];

mac.doFinal(hash,0);returnhash;

}public static String hmacSm3Hex(byte[] key, byte[] srcData) {byte[] hash =hmacSm3(key, srcData);

String hexString=org.apache.commons.codec.binary.Hex.encodeHexString(hash);returnhexString;

}public static byte[] sm3bc(byte[] srcData) throwsException {

MessageDigest messageDigest= MessageDigest.getInstance("SM3", "BC");byte[] digest =messageDigest.digest(srcData);returndigest;

}public static String sm3bcHex(byte[] srcData) throwsException {byte[] hash =sm3bc(srcData);

String hexString=org.apache.commons.codec.binary.Hex.encodeHexString(hash);returnhexString;

}

}

测试

public classBcSm3UtilTest {private String test="woshi测试数据。。..";

@Testpublic void sm3() throwsException {

String s=BcSm3Util.sm3Hex(test.getBytes());

System.out.println(s);

String s2=BcSm3Util.sm3bcHex(test.getBytes());

System.out.println(s2);

Assert.assertEquals(s,s2);

}

@Testpublic voidhmacSm3Hex() {

String s= BcSm3Util.hmacSm3Hex("AAAA".getBytes(),test.getBytes());

System.out.println(s);

}

}

1.4、SM4

public classBcSm4Util {static{

Security.addProvider(newBouncyCastleProvider());

}public static final String ALGORITHM_NAME = "SM4";public static final String DEFAULT_KEY = "random_seed";//128-32位16进制;256-64位16进制

public static final int DEFAULT_KEY_SIZE = 128;static{

Security.addProvider(newBouncyCastleProvider());

}public static byte[] generateKey() throwsNoSuchAlgorithmException, NoSuchProviderException {returngenerateKey(DEFAULT_KEY, DEFAULT_KEY_SIZE);

}public static byte[] generateKey(String seed) throwsNoSuchAlgorithmException, NoSuchProviderException {returngenerateKey(seed, DEFAULT_KEY_SIZE);

}public static byte[] generateKey(String seed, int keySize) throwsNoSuchAlgorithmException, NoSuchProviderException {

KeyGenerator kg=KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);

SecureRandom random= SecureRandom.getInstance("SHA1PRNG");if (null != seed && !"".equals(seed)) {

random.setSeed(seed.getBytes());

}

kg.init(keySize, random);returnkg.generateKey().getEncoded();

}/*** @description 加密*/

public static byte[] encrypt(String algorithmName, byte[] key, byte[] iv, byte[] data) throwsException {returnsm4core(algorithmName,Cipher.ENCRYPT_MODE, key, iv, data);

}/*** @description 解密*/

public static byte[] decrypt(String algorithmName, byte[] key, byte[] iv, byte[] data) throwsException {returnsm4core(algorithmName, Cipher.DECRYPT_MODE, key, iv, data);

}private static byte[] sm4core(String algorithmName, int type, byte[] key, byte[] iv, byte[] data) throwsException {

Cipher cipher=Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);

Key sm4Key= newSecretKeySpec(key, ALGORITHM_NAME);if (algorithmName.contains("/ECB/")) {

cipher.init(type, sm4Key);

}else{

IvParameterSpec ivParameterSpec= newIvParameterSpec(iv);

cipher.init(type, sm4Key, ivParameterSpec);

}returncipher.doFinal(data);

}

}

测试

public classBcSm4UtilTest {byte[] key =BcSm4Util.generateKey();byte[] iv = null;

String text= "我是加密数据,请测试。。8888";public BcSm4UtilTest() throwsNoSuchProviderException, NoSuchAlgorithmException {

}

@Testpublic void bcSm4UtilTest() throwsException {

List algorithm = new ArrayList<>();

algorithm.add(("SM4/ECB/NOPADDING"));

algorithm.add(("SM4/ECB/PKCS5PADDING"));

algorithm.add(("SM4/ECB/ISO10126PADDING"));

algorithm.add(("SM4/CBC/NOPADDING"));

algorithm.add(("SM4/CBC/PKCS5PADDING"));

algorithm.add(("SM4/CBC/ISO10126PADDING"));

algorithm.add(("SM4/PCBC/NOPADDING"));

algorithm.add(("SM4/PCBC/PKCS5PADDING"));

algorithm.add(("SM4/PCBC/ISO10126PADDING"));

algorithm.add(("SM4/CTR/NOPADDING"));

algorithm.add(("SM4/CTR/PKCS5PADDING"));

algorithm.add(("SM4/CTR/ISO10126PADDING"));

algorithm.add(("SM4/CTS/NOPADDING"));

algorithm.add(("SM4/CTS/PKCS5PADDING"));

algorithm.add(("SM4/CTS/ISO10126PADDING"));if (iv == null)

iv= AbstractSymmetric.initIv(16);for(String s : algorithm) {//SM4加密

try{

System.out.println("SM4加密算法: " +s);

System.out.println("SM4加密原始数据: " +text);

System.out.println("SM4加密key: " +Base64.getEncoder().encodeToString(key));

System.out.println("SM4加密iv: " +Base64.getEncoder().encodeToString(iv));byte[] encrypt =BcSm4Util.encrypt(s, key, iv, text.getBytes());

System.out.println("SM4加密数据密文: " +Base64.getEncoder().encodeToString(encrypt));//SM4解密

byte[] decrypt =BcSm4Util.decrypt(s, key, iv, encrypt);

System.out.println("SM4解密数据: " + newString(decrypt));

}catch(Exception e) {if (e instanceofIllegalBlockSizeException) {

System.err.println("SM4解密数据:算法 " + s + "数据需自己手工对齐");

}else{

System.err.println("SM4解密数据:算法 " + s +"::"+e.getMessage());

}

}finally{

System.err.println("---------------------------------------");

TimeUnit.SECONDS.sleep(1);

}

}

}

}

水电费

java信息安全性_java-信息安全(二十)国密算法 SM1,SM2,SM3,SM4相关推荐

  1. 国密算法SM1/SM2/SM3/SM4

    原创不易,转载请注明出处. 国密算法由国家密码局发布,今天大概介绍4中国密算法,分别是SM1,SM2,SM3,SM4.他们之间异同通过下表展示. 算法名称 算法分类 算法是否公开 明文最大长度(bit ...

  2. 浅谈国密算法 SM1、SM2、SM3、SM4

    浅谈国密算法 国密算法是我国自主研发创新的一套数据加密处理系列算法.从SM1-SM4分别实现了对称.非对称.摘要等算法功能.特别适合应用于嵌入式物联网等相关领域,完成身份认证和数据加解密等功能.当然, ...

  3. 关于国密算法 SM1,SM2,SM3,SM4 的笔记

    关于国密算法 SM1,SM2,SM3,SM4 的笔记 国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4.密钥长度和分组长度均为128位. SM1 为对称加密.其加密强度与AES ...

  4. 国密SM1\ SM2\ SM3\ SM4\ SSF33算法和国际RSA算法的对应关系

    转载自https://blog.csdn.net/hcnetbee/article/details/53692579,部分内容和排版稍作修改. 国密算法由国家密码局发布,包含SM1\ SM2\ SM3 ...

  5. 【转】关于国密算法 SM1,SM2,SM3,SM4 的笔记

    国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4.密钥长度和分组长度均为128位. SM1 为对称加密.其加密强度与AES相当.该算法不公开,调用该算法时,需要通过加密芯片的接 ...

  6. 国密算法 SM1,SM2,SM3,SM4 -小白笔记

    国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4. SM1 为对称加密.其加密强度与AES相当.该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用. SM2为非对称加密 ...

  7. 国密算法SM1,SM2,SM3,SM4的研究

    国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4,SM7,SM9,祖冲之密码算法(ZUC).密钥长度和分组长度均为128位.其中SM1.SM4.SM7.祖冲之密码(ZUC)是对 ...

  8. 爬虫逆向基础,认识 SM1/SM2/SM3/SM4/SM7/SM9/ZUC 国密算法

    文章目录 [01x00] 简介 [02x00]算法概述 [03x00]算法详解 [03x01]SM1 分组加密算法 [03x02]SM2 椭圆曲线公钥加密算法 [03x03]SM3 杂凑算法 [03x ...

  9. 国密算法(SM1,SM2,SM3,SM4)和国际算法对应关系

    加密领域主要有国际算法和国密算法两种体系.国密算法是国家密码局认定的国产密码算法.国际算法是由美国安全局发布的算法.由于国密算法安全性高等一系列原因.国内的银行和支付机构都推荐使用国密算法. 国密与国 ...

  10. 密码学系列 - 国密算法SM1/SSF33

    国密分组密码 SM1分组密码和SSF33分组密码均为国密分组密码标标准,SM1和SSF33的密钥长度和分组长度均为128比特. 目前这两个分组密码标准的算法尚未公开,其实现仅可以通过硬件芯片的方式获得 ...

最新文章

  1. Java文件流输入输出
  2. sublime text使用正则表达式批量给KV加
  3. Oracle查看死锁 .
  4. import是引进外部函数吗_vue3已正式发布,你学了吗
  5. 曲线绕x轴旋转曲面方程_几何代数50 ----柱面及其方程
  6. springboot 手动提交事务_面试官你都工作3年了,也做过5个项目了,怎么连事务机制都不会...
  7. CentOS下redis安装和部署
  8. 六石管理学:座位可以考虑混排
  9. java jsp乱码怎么解决_Java/JSP中文乱码问题解决心得
  10. linux大容量硬盘 克隆到小硬盘_clonezilla 不管用了,手动把 GPT 分区的 ubuntu14.04 从大硬盘克隆到小硬盘...
  11. 基于python提火车票信息_python3.X 抓取火车票信息【修正版】
  12. 电脑win10无法自动修复此计算机,如何解决Win10自动修复无法修复你的电脑?
  13. UVA 10635 Prince and Princess
  14. XML数据交换的安全解决方案
  15. Mysql断流_彻底解决ROS网页断流问题
  16. STM32双轴摇杆控制空心杯电机
  17. APS实现的要点与难点
  18. Windows 安装Docker 打包镜像
  19. PHPWAMP安装Redis扩展的方式与相关扩展的下载
  20. autojs注入webview

热门文章

  1. Python继承初始化问题
  2. 二次函数顶点式计算机,二次函数顶点式是什么
  3. xbox手柄适配器驱动_将Xbox MN-740无线适配器的固件刷新到D-Link 108AG以支持WPA安全...
  4. 计算机串口无法发数,单片机向电脑发送数据,为什么串口调试助手收不到数据 求助...
  5. 计算机模拟合理用药,计算机模拟地塞米松在内耳药物动力学与内耳显微结构三维重建的实验研究...
  6. java的特征多态,java基础(三)—–java的三大特征之多态
  7. 逻辑回归报错解决方案ConvergenceWarning: lbfgs failed to converge
  8. 电商用户购买行为数据分析
  9. DNA框架下error in opening zip file
  10. Qz学算法-数据结构篇(链表、栈)