国产密码算法介绍 SM2/SM3/SM4/SM9/祖冲之ZUC

链接:

对称加密算法详解

非对称加密算法详解

目录

一、对称加密算法

二、非对称加密算法

三、杂凑(哈希)算法

四、各种算法对比一览表

五、如何应用

五、C#中应用国产加密算法

准备工作

代码示例

1. SM4 加密与解密示例

2. SM2 签名与验签示例

3. SM3 哈希计算示例

六、Java中应用国产加密算法

准备工作

代码示例

1. SM4 加密与解密示例

2. SM2 签名与验签示例

3. SM3 哈希计算示例

七、相关资料

1. 国家密码管理局网站

2. 商用密码检测中心


国产加密算法,通常也称为国密算法或商用密码算法,是由中国国家密码管理局制定的一系列加密标准。这些算法旨在提供与国际通用的加密算法相同的功能,同时确保中国的信息化系统能够拥有自主可控的安全保障。

一、对称加密算法

  1. SM1 算法:由国家密码管理局编制的一种商用密码分组标准对称算法,其分组长度和密钥长度均为 128 位。该算法的安全保密强度及相关软硬件实现性能与 AES 算法相当。值得注意的是,SM1 算法尚未公开,仅以 IP 核的形式存在于芯片中,广泛应用于电子政务、电子商务及国民经济的各个应用领域。
  2. SM4 算法:我国自主研发的分组对称密码算法,用于数据的加密和解密运算。它的分组长度和密钥长度同样为 128 比特,并具有较高的安全性和计算效率。加密算法与密钥扩展算法都采用 32 轮非线性迭代结构。解密算法与加密算法结构相同,只是轮密钥的使用顺序相反。
  3. SM7 算法:一种分组密码算法,分组长度为 128 比特,密钥长度也是 128 比特。它特别适用于非接 IC 卡的应用场景,包括身份识别类应用、票务类应用、支付与通卡类应用等。
  4. 祖冲之密码算法(ZUC):中国自主研究的流密码算法,是运用于移动通信 4G 网络中的国际标准密码算法。该算法体系包含了祖冲之算法、加密算法和完整性算法三个部分,确保了通信过程中的数据安全性和完整性。

二、非对称加密算法

  1. SM2 算法:基于椭圆曲线密码学(ECC)的非对称密钥算法,其加密强度为 256 位。SM2 包含椭圆曲线数字签名算法、密钥交换协议和公钥加密算法,分别用于实现数字签名、密钥协商和数据加密等功能。相比于 RSA1024,SM2 在安全性方面具有明显优势,同时在签名速度与密钥生成速度上也更快。
  2. SM9 算法:这是一种基于标识的密码算法,类似于 SM2,但包含总则、数字签名算法、密钥交换协议以及密钥封装机制和公钥加密算法。SM9 实现了一种基于身份的密码体制,其中公钥直接与用户的身份信息即标识相关联,因此省去了证书管理的需求,非常适合互联网应用的各种新兴应用场景,提供了更便捷的安全保障。

杂凑(哈希)算法

  1. SM3算法:SM3是中国商用密码标准中指定的密码杂凑算法,它是一个基于Merkle-Damgard结构的迭代型算法,能够将输入的消息处理成一个256位的固定长度摘要。该算法可替代 MD5/SHA - 1/SHA - 2 等国际算法,能满足电子认证服务系统等应用需求。

四、各种算法对比一览表

类别

算法名称

概述

特点

应用场景

对称加密算法

SM1 算法

由国家密码管理局编制的一种商用密码分组标准对称算法,分组长度和密钥长度均为 128 位。

安全保密强度与 AES 算法相当,尚未公开,仅以 IP 核形式存在于芯片中。

广泛应用于电子政务、电子商务及国民经济的各个应用领域。

SM4 算法

我国自主研发的分组对称密码算法,用于实现数据的加密和解密运算。

分组长度和密钥长度均为 128 比特,采用 32 轮非线性迭代结构,具有较高的安全性和计算效率。

适用于需要高效加密的各种场景,如电子政务、电子商务等。

SM7 算法

一种分组密码算法,专为非接 IC 卡应用设计。

分组长度为 128 比特,密钥长度也为 128 比特,适合资源受限的环境。

包括身份识别类应用、票务类应用、支付与通卡类应用等。

祖冲之密码算法(ZUC)

中国自主研究的流密码算法,是移动通信 4G 网络中的国际标准密码算法。

包含祖冲之算法、加密算法和完整性算法三个部分,确保通信过程中的数据安全性和完整性。

主要用于移动通信领域,保障数据传输的安全。

非对称加密算法

SM2 算法

基于椭圆曲线密码学(ECC)的非对称密钥算法,提供数字签名、密钥交换和公钥加密功能。

加密强度为 256 位,相比 RSA1024 在安全性方面具有明显优势,且签名速度与密钥生成速度更快。

适用于高安全需求的场合,如电子签章、网络认证等。

SM9 算法

基于标识的密码算法,允许直接使用用户的身份信息作为公钥。

省去了证书管理的需求,提供了更便捷的安全保障机制。

特别适合互联网应用的各种新兴场景,如云服务、物联网等,其中需要简便且高效的安全措施。

杂凑(哈希)算法

SM3算法

密码杂凑算法,能够将输入的消息处理成一个256位的固定长度摘要。

具有256位固定长度输出,通过多轮迭代和复杂的压缩函数确保高安全性,能有效抵抗碰撞攻击和原像攻击

适用于数字签名、消息认证码、数据完整性校验、密码存储、区块链等场景。

五、如何应用

1. BouncyCastle库

BouncyCastle是一个开源的加密库,支持多种加密算法,包括SM2/SM4。支持Java、C#等编程语言

下载地址:Bouncy Castle open-source cryptographic APIs

2. Gmssl库

一个支持国密算法的库,支持Java、Python、go、php、js等语言。

GitHub地址:https://github.com/guanzhi/GmSSL

五、C#中应用国产加密算法

准备工作

1.通过 NuGet 安装 Bouncy Castle 库。

Install-Package Portable.BouncyCastle

2. 在代码中引入必要的命名空间:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Math;
using System.Text;

代码示例

1. SM4 加密与解密示例

SM4 是一种分组对称加密算法,分组长度为 128 比特(16 字节),支持 CBC 模式。

using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;

public class SM4Example
{
    public static void Main(string[] args)
    {
        byte[] key = HexToBytes("0123456789ABCDEFFEDCBA9876543210"); // 16字节密钥
        byte[] iv = HexToBytes("1234567890ABCDEF1234567890ABCDEF");  // 16字节IV
        string plainText = "Hello, SM4!";

        // 加密
        byte[] encrypted = SM4Encrypt(key, iv, Encoding.UTF8.GetBytes(plainText));
        Console.WriteLine("加密结果: " + BytesToHex(encrypted));

        // 解密
        byte[] decrypted = SM4Decrypt(key, iv, encrypted);
        Console.WriteLine("解密结果: " + Encoding.UTF8.GetString(decrypted));
    }

    public static byte[] SM4Encrypt(byte[] key, byte[] iv, byte[] data)
    {
        var cipher = new CbcBlockCipher(new SM4Engine());
        var parameters = new ParametersWithIV(new KeyParameter(key), iv);
        cipher.Init(true, parameters);

        byte[] output = new byte[cipher.GetOutputSize(data.Length)];
        int length = cipher.ProcessBytes(data, 0, data.Length, output, 0);
        cipher.DoFinal(output, length);
        return output;
    }

    public static byte[] SM4Decrypt(byte[] key, byte[] iv, byte[] data)
    {
        var cipher = new CbcBlockCipher(new SM4Engine());
        var parameters = new ParametersWithIV(new KeyParameter(key), iv);
        cipher.Init(false, parameters);

        byte[] output = new byte[cipher.GetOutputSize(data.Length)];
        int length = cipher.ProcessBytes(data, 0, data.Length, output, 0);
        cipher.DoFinal(output, length);
        return output;
    }

    private static byte[] HexToBytes(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }

    private static string BytesToHex(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        foreach (byte b in bytes)
            sb.Append(b.ToString("X2"));
        return sb.ToString();
    }
}

2. SM2 签名与验签示例

SM2 是一种基于椭圆曲线密码学(ECC)的非对称加密算法,常用于数字签名。

using System;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;

public class SM2Example
{
    public static void Main(string[] args)
    {
        // 生成SM2密钥对
        AsymmetricCipherKeyPair keyPair = GenerateSM2KeyPair();
        ECPublicKeyParameters publicKey = (ECPublicKeyParameters)keyPair.Public;
        ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters)keyPair.Private;

        string message = "Hello, SM2!";
        byte[] messageBytes = Encoding.UTF8.GetBytes(message);

        // 签名
        byte[] signature = Sign(privateKey, messageBytes);
        Console.WriteLine("签名结果: " + BytesToHex(signature));

        // 验签
        bool isValid = Verify(publicKey, messageBytes, signature);
        Console.WriteLine("验签结果: " + isValid);
    }

    public static AsymmetricCipherKeyPair GenerateSM2KeyPair()
    {
        var keyGen = new ECKeyPairGenerator();
        var keyGenParams = new ECKeyGenerationParameters(GMObjectIdentifiers.sm2p256v1, new SecureRandom());
        keyGen.Init(keyGenParams);
        return keyGen.GenerateKeyPair();
    }

    public static byte[] Sign(ECPrivateKeyParameters privateKey, byte[] data)
    {
        ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
        signer.Init(true, privateKey);
        signer.BlockUpdate(data, 0, data.Length);
        return signer.GenerateSignature();
    }

    public static bool Verify(ECPublicKeyParameters publicKey, byte[] data, byte[] signature)
    {
        ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
        signer.Init(false, publicKey);
        signer.BlockUpdate(data, 0, data.Length);
        return signer.VerifySignature(signature);
    }

    private static string BytesToHex(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        foreach (byte b in bytes)
            sb.Append(b.ToString("X2"));
        return sb.ToString();
    }
}

3. SM3 哈希计算示例

SM3 是一种哈希算法,输出为 256 位(32 字节)。

using System;
using Org.BouncyCastle.Crypto.Digests;

public class SM3Example
{
    public static void Main(string[] args)
    {
        string input = "Hello, SM3!";
        byte[] hash = ComputeSM3(Encoding.UTF8.GetBytes(input));
        Console.WriteLine("SM3 哈希值: " + BytesToHex(hash));
    }

    public static byte[] ComputeSM3(byte[] data)
    {
        var digest = new SM3Digest();
        digest.BlockUpdate(data, 0, data.Length);
        byte[] result = new byte[digest.GetDigestSize()];
        digest.DoFinal(result, 0);
        return result;
    }

    private static string BytesToHex(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        foreach (byte b in bytes)
            sb.Append(b.ToString("X2"));
        return sb.ToString();
    }
}

六、Java中应用国产加密算法

准备工作

1. 安装 Bouncy Castle for Java:

在 Maven 项目中添加依赖:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version> <!-- 使用最新版本 -->
</dependency>

2.引入命名空间

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version> <!-- 使用最新版本 -->
</dependency>

代码示例

1. SM4 加密与解密示例

SM4 是一种分组对称加密算法,支持 CBC 模式。

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.util.Base64;

public class SM4Example {
    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        String keyHex = "0123456789ABCDEFFEDCBA9876543210"; // 16字节密钥
        String ivHex = "1234567890ABCDEF1234567890ABCDEF";  // 16字节IV
        String plainText = "Hello, SM4!";

        byte[] key = hexToBytes(keyHex);
        byte[] iv = hexToBytes(ivHex);

        // 加密
        byte[] encrypted = sm4Encrypt(key, iv, plainText.getBytes());
        System.out.println("加密结果: " + Base64.getEncoder().encodeToString(encrypted));

        // 解密
        byte[] decrypted = sm4Decrypt(key, iv, encrypted);
        System.out.println("解密结果: " + new String(decrypted));
    }

    public static byte[] sm4Encrypt(byte[] key, byte[] iv, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
        SecretKeySpec keySpec = new SecretKeySpec(key, "SM4");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        return cipher.doFinal(data);
    }

    public static byte[] sm4Decrypt(byte[] key, byte[] iv, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
        SecretKeySpec keySpec = new SecretKeySpec(key, "SM4");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        return cipher.doFinal(data);
    }

    private static byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }
}

2. SM2 签名与验签示例

SM2 是一种基于椭圆曲线密码学(ECC)的非对称加密算法。

import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;

import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;

public class SM2Example {
    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        String message = "Hello, SM2!";
        KeyPair keyPair = generateSM2KeyPair();

        // 签名
        byte[] signature = sign((PrivateKey) keyPair.getPrivate(), message.getBytes());
        System.out.println("签名结果: " + Base64.getEncoder().encodeToString(signature));

        // 验签
        boolean isValid = verify((PublicKey) keyPair.getPublic(), message.getBytes(), signature);
        System.out.println("验签结果: " + isValid);
    }

    public static KeyPair generateSM2KeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", "BC");
        ECGenParameterSpec ecSpec = new ECGenParameterSpec("sm2p256v1");
        keyGen.initialize(ecSpec, new SecureRandom());
        return keyGen.generateKeyPair();
    }

    public static byte[] sign(PrivateKey privateKey, byte[] data) throws Exception {
        Signature signer = Signature.getInstance("SM3withSM2", "BC");
        signer.initSign(privateKey);
        signer.update(data);
        return signer.sign();
    }

    public static boolean verify(PublicKey publicKey, byte[] data, byte[] signature) throws Exception {
        Signature verifier = Signature.getInstance("SM3withSM2", "BC");
        verifier.initVerify(publicKey);
        verifier.update(data);
        return verifier.verify(signature);
    }
}

3. SM3 哈希计算示例

SM3 是一种哈希算法,输出为 256 位(32 字节)。

import org.bouncycastle.crypto.digests.SM3Digest;
import java.util.Base64;

public class SM3Example {
    public static void main(String[] args) {
        String input = "Hello, SM3!";
        byte[] hash = computeSM3(input.getBytes());
        System.out.println("SM3 哈希值: " + Base64.getEncoder().encodeToString(hash));
    }

    public static byte[] computeSM3(byte[] data) {
        SM3Digest digest = new SM3Digest();
        digest.update(data, 0, data.length);
        byte[] result = new byte[digest.getDigestSize()];
        digest.doFinal(result, 0);
        return result;
    }
}

七、相关资料

1. 国家密码管理局网站

国家密码管理局

2. 商用密码检测中心

商用密码检测认证中心_下载中心算法源代码_源代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值