国密算法SM2、SM3的使用

这篇具有很好参考价值的文章主要介绍了国密算法SM2、SM3的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、SM2、SM3介绍:

1. SM2是非对称加密算法

        它是基于椭圆曲线密码的公钥密码算法标准,其秘钥长度256bit,包含数字签名、密钥交换和公钥加密,用于替换RSA/DH/ECDSA/ECDH等国际算法。可以满足电子认证服务系统等应用需求,由国家密码管理局于2010年12月17号发布。

2.SM3是一种密码杂凑算法

        用于替代MD5/SHA-1/SHA-2等国际算法,适用于数字签名和验证、消息认证码的生成与验证以及随机数的生成,可以满足电子认证服务系统等应用需求,于2010年12月17日发布。它是在SHA-256基础上改进实现的一种算法,采用Merkle-Damgard结构,消息分组长度为512bit,输出的摘要值长度为256bit。

二、SM2、SM3在项目中的使用:

        SM2用于前后端密码加密传输,SM3用于数据库密码加密。

三、SM2在项目中具体使用

1. 前端部分关键代码

1.1 npm安装国密

npm install --save sm-crypto

1.2 vue中引用国密

const sm2 = require('sm-crypto').sm2;  // 引用国密
const cipherMode = 1;  // 密文排列方式0-C1C2C3;1-C1C3C2

1.3 data中定义公钥public

data() {
    return {
      codeUrl: "",
      loginForm: {
        username: "admin",
        password: "admin",
        rememberMe: false,
        code: "",
        uuid: "",
        pubKey:"", // 自己的公钥,这里后端返回后赋值
      },
    }
}

1.4将密码加密后传到后端

const passwordEn = sm2.doEncrypt(password,pubKey,cipherMode);

2.后端关键代码

2.1 依赖 pom.xml

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.57</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-ext-jdk15on</artifactId>
            <version>1.57</version>
        </dependency>

2.2 扩展类 SM2EngineExtend.java

/**
 * 对org.bouncycastle:bcprov-jdk15on:1.57扩展
 * <br/>BC库加密结果是按C1C2C3,国密标准是C1C3C2(加密芯片也是这个排列),
 * <br/>本扩展主要实现加密结果排列方式可选
 */
public class SM2EngineExtend {
    private final Digest digest;

    /**是否为加密模式*/
    private boolean forEncryption;
    private ECKeyParameters ecKey;
    private ECDomainParameters ecParams;
    private int curveLength;
    private SecureRandom random;
    /**密文排序方式*/
    private int cipherMode;

    /**BC库默认排序方式-C1C2C3*/
    public static int CIPHERMODE_BC = 0;
    /**国密标准排序方式-C1C3C2*/
    public static int CIPHERMODE_NORM = 1;

    public SM2EngineExtend() {
        this(new SM3Digest());
    }

    public SM2EngineExtend(Digest digest) {
        this.digest = digest;
    }

    /**
     * 设置密文排序方式
     * @param cipherMode
     */
    public void setCipherMode(int cipherMode){
        this.cipherMode = cipherMode;
    }

    /**
     * 默认初始化方法,使用国密排序标准
     * @param forEncryption - 是否以加密模式初始化
     * @param param - 曲线参数
     */
    public void init(boolean forEncryption, CipherParameters param) {
        init(forEncryption, CIPHERMODE_NORM, param);
    }

    /**
     * 默认初始化方法,使用国密排序标准
     * @param forEncryption 是否以加密模式初始化
     * @param cipherMode 加密数据排列模式:1-标准排序;0-BC默认排序
     * @param param 曲线参数
     */
    public void init(boolean forEncryption, int cipherMode, CipherParameters param) {
        this.forEncryption = forEncryption;
        this.cipherMode = cipherMode;
        if (forEncryption) {
            ParametersWithRandom rParam = (ParametersWithRandom) param;

            ecKey = (ECKeyParameters) rParam.getParameters();
            ecParams = ecKey.getParameters();

            ECPoint s = ((ECPublicKeyParameters) ecKey).getQ().multiply(ecParams.getH());
            if (s.isInfinity()) {
                throw new IllegalArgumentException("invalid key: [h]Q at infinity");
            }

            random = rParam.getRandom();
        } else {
            ecKey = (ECKeyParameters) param;
            ecParams = ecKey.getParameters();
        }

        curveLength = (ecParams.getCurve().getFieldSize() + 7) / 8;
    }

    /**
     * 加密或解密输入数据
     * @param in
     * @param inOff
     * @param inLen
     * @return
     * @throws InvalidCipherTextException
     */
    public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
        if (forEncryption) {
            // 加密
            return encrypt(in, inOff, inLen);
        } else {
            return decrypt(in, inOff, inLen);
        }
    }

    /**
     * 加密实现,根据cipherMode输出指定排列的结果,默认按标准方式排列
     * @param in
     * @param inOff
     * @param inLen
     * @return
     * @throws InvalidCipherTextException
     */
    private byte[] encrypt(byte[] in, int inOff, int inLen)
            throws InvalidCipherTextException {
        byte[] c2 = new byte[inLen];

        System.arraycopy(in, inOff, c2, 0, c2.length);

        byte[] c1;
        ECPoint kPB;
        do {
            BigInteger k = nextK();

            ECPoint c1P = ecParams.getG().multiply(k).normalize();

            c1 = c1P.getEncoded(false);

            kPB = ((ECPublicKeyParameters) ecKey).getQ().multiply(k).normalize();

            kdf(digest, kPB, c2);
        }
        while (notEncrypted(c2, in, inOff));

        byte[] c3 = new byte[digest.getDigestSize()];

        addFieldElement(digest, kPB.getAffineXCoord());
        digest.update(in, inOff, inLen);
        addFieldElement(digest, kPB.getAffineYCoord());

        digest.doFinal(c3, 0);
        if (cipherMode == CIPHERMODE_NORM){
            return Arrays.concatenate(c1, c3, c2);
        }
        return Arrays.concatenate(c1, c2, c3);
    }

    /**
     * 解密实现,默认按标准排列方式解密,解密时解出c2部分原文并校验c3部分
     * @param in
     * @param inOff
     * @param inLen
     * @return
     * @throws InvalidCipherTextException
     */
    private byte[] decrypt(byte[] in, int inOff, int inLen)
            throws InvalidCipherTextException {
        byte[] c1 = new byte[curveLength * 2 + 1];

        System.arraycopy(in, inOff, c1, 0, c1.length);

        ECPoint c1P = ecParams.getCurve().decodePoint(c1);

        ECPoint s = c1P.multiply(ecParams.getH());
        if (s.isInfinity()) {
            throw new InvalidCipherTextException("[h]C1 at infinity");
        }

        c1P = c1P.multiply(((ECPrivateKeyParameters) ecKey).getD()).normalize();

        byte[] c2 = new byte[inLen - c1.length - digest.getDigestSize()];
        if (cipherMode == CIPHERMODE_BC) {
            System.arraycopy(in, inOff + c1.length, c2, 0, c2.length);
        }else{
            // C1 C3 C2
            System.arraycopy(in, inOff + c1.length + digest.getDigestSize(), c2, 0, c2.length);
        }

        kdf(digest, c1P, c2);

        byte[] c3 = new byte[digest.getDigestSize()];

        addFieldElement(digest, c1P.getAffineXCoord());
        digest.update(c2, 0, c2.length);
        addFieldElement(digest, c1P.getAffineYCoord());

        digest.doFinal(c3, 0);

        int check = 0;
        // 检查密文输入值C3部分和由摘要生成的C3是否一致
        if (cipherMode == CIPHERMODE_BC) {
            for (int i = 0; i != c3.length; i++) {
                check |= c3[i] ^ in[c1.length + c2.length + i];
            }
        }else{
            for (int i = 0; i != c3.length; i++) {
                check |= c3[i] ^ in[c1.length + i];
            }
        }

        clearBlock(c1);
        clearBlock(c3);

        if (check != 0) {
            clearBlock(c2);
            throw new InvalidCipherTextException("invalid cipher text");
        }

        return c2;
    }

    private boolean notEncrypted(byte[] encData, byte[] in, int inOff) {
        for (int i = 0; i != encData.length; i++) {
            if (encData[i] != in[inOff]) {
                return false;
            }
        }

        return true;
    }

    private void kdf(Digest digest, ECPoint c1, byte[] encData) {
        int ct = 1;
        int v = digest.getDigestSize();

        byte[] buf = new byte[digest.getDigestSize()];
        int off = 0;

        for (int i = 1; i <= ((encData.length + v - 1) / v); i++) {
            addFieldElement(digest, c1.getAffineXCoord());
            addFieldElement(digest, c1.getAffineYCoord());
            digest.update((byte) (ct >> 24));
            digest.update((byte) (ct >> 16));
            digest.update((byte) (ct >> 8));
            digest.update((byte) ct);

            digest.doFinal(buf, 0);

            if (off + buf.length < encData.length) {
                xor(encData, buf, off, buf.length);
            } else {
                xor(encData, buf, off, encData.length - off);
            }

            off += buf.length;
            ct++;
        }
    }

    private void xor(byte[] data, byte[] kdfOut, int dOff, int dRemaining) {
        for (int i = 0; i != dRemaining; i++) {
            data[dOff + i] ^= kdfOut[i];
        }
    }

    private BigInteger nextK() {
        int qBitLength = ecParams.getN().bitLength();

        BigInteger k;
        do {
            k = new BigInteger(qBitLength, random);
        }
        while (k.equals(ECConstants.ZERO) || k.compareTo(ecParams.getN()) >= 0);

        return k;
    }

    private void addFieldElement(Digest digest, ECFieldElement v) {
        byte[] p = BigIntegers.asUnsignedByteArray(curveLength, v.toBigInteger());

        digest.update(p, 0, p.length);
    }

    /**
     * clear possible sensitive data
     */
    private void clearBlock(
            byte[] block) {
        for (int i = 0; i != block.length; i++) {
            block[i] = 0;
        }
    }

}

2.3 SM2加解密工具类Sm2Util.java

public class Sm2Util {
    /**
     * 获取sm2密钥对
     * BC库使用的公钥=64个字节+1个字节(04标志位),BC库使用的私钥=32个字节
     * SM2秘钥的组成部分有 私钥D 、公钥X 、 公钥Y , 他们都可以用长度为64的16进制的HEX串表示,
     * <br/>SM2公钥并不是直接由X+Y表示 , 而是额外添加了一个头,当启用压缩时:公钥=有头+公钥X ,即省略了公钥Y的部分
     *
     * @param compressed 是否压缩公钥(加密解密都使用BC库才能使用压缩)
     * @return
     */
    public static String[] getSm2Keys(boolean compressed) {
        //获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName(Constant.CRYPTO_NAME_SM2);
        //构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        //1.创建密钥生成器
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
        //2.初始化生成器,带上随机数
        try {
            keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
        } catch (NoSuchAlgorithmException e) {
            System.out.println(e.getMessage());
        }
        //3.生成密钥对
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
        ECPublicKeyParameters publicKeyParameters = (ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic();
        ECPoint ecPoint = publicKeyParameters.getQ();
        // 把公钥放入map中,默认压缩公钥
        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥,04的时候,可以去掉前面的04
        String publicKey = Hex.toHexString(ecPoint.getEncoded(compressed));
        ECPrivateKeyParameters privateKeyParameters = (ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate();
        BigInteger intPrivateKey = privateKeyParameters.getD();
        // 把私钥放入map中
        String privateKey = intPrivateKey.toString(16);
        String[] KeyPairOfString = new String[2];
        KeyPairOfString[0] = publicKey;
        KeyPairOfString[1] = privateKey;

        return KeyPairOfString;
    }
    /**
     * SM2加密算法
     * @param publicKey 公钥
     * @param data 待加密的数据
     * @return 密文,BC库产生的密文带由04标识符,与非BC库对接时需要去掉开头的04
     */
    public static String encrypt(String publicKey, String data){
        // 按国密排序标准加密
        return encrypt(publicKey, data, SM2EngineExtend.CIPHERMODE_NORM);
    }

    /**
     * SM2加密算法
     * @param publicKey 公钥
     * @param data 待加密的数据
     * @param cipherMode 密文排列方式0-C1C2C3;1-C1C3C2;
     * @return 密文,BC库产生的密文带由04标识符,与非BC库对接时需要去掉开头的04
     */
    public static String encrypt(String publicKey, String data, int cipherMode) {
        // 获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName(Constant.CRYPTO_NAME_SM2);
        // 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数N
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        //提取公钥点
        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

        SM2EngineExtend sm2Engine = new SM2EngineExtend();
        // 设置sm2为加密模式
        sm2Engine.init(true, cipherMode, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes();
            arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return Hex.toHexString(arrayOfBytes);
    }

    /**
     * SM2解密算法
     * @param privateKey    私钥
     * @param cipherData    密文数据
     * @return
     */
    public static String decrypt(String privateKey, String cipherData) {
        // // 按国密排序标准解密
        return decrypt(privateKey, cipherData, SM2EngineExtend.CIPHERMODE_NORM);
    }

    /**
     * SM2解密算法
     * @param privateKey    私钥
     * @param cipherData    密文数据
     * @param cipherMode 密文排列方式0-C1C2C3;1-C1C3C2;
     * @return
     */
    public static String decrypt(String privateKey, String cipherData, int cipherMode) {
        // 使用BC库加解密时密文以04开头,传入的密文前面没有04则补上
        if (!cipherData.startsWith("04")) {
            cipherData = "04" + cipherData;
        }
        byte[] cipherDataByte = Hex.decode(cipherData);

        //获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName(Constant.CRYPTO_NAME_SM2);
        //构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());

        BigInteger privateKeyD = new BigInteger(privateKey, 16);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

        SM2EngineExtend sm2Engine = new SM2EngineExtend();
        // 设置sm2为解密模式
        sm2Engine.init(false, cipherMode, privateKeyParameters);

        String result = "";
        try {
            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
            return new String(arrayOfBytes);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return result;
    }

    /**
     * 私钥签名
     *
     * @param data 未加密的密码明文
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static byte[] signByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
        Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);
        sig.initSign(privateKey);
        sig.update(data);
        byte[] ret = sig.sign();
        return ret;
    }

    /**
     * 公钥验签
     *
     * @param data 未加密的密码明文
     * @param publicKey
     * @param signature 签名
     * @return
     * @throws Exception
     */
    public static boolean verifyByPublicKey(byte[] data, PublicKey publicKey, byte[] signature) throws Exception {
        Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);
        sig.initVerify(publicKey);
        sig.update(data);
        boolean ret = sig.verify(signature);
        return ret;
    }
}

2.4 测试类 EncryptAndDecryptTest.java

@SpringBootTest
public class EncryptAndDecryptTest {

    private String pwd = "123456";

    @Test
    void testEncryptAndDecrypt(){
        System.out.println("未加密密码:"+pwd);
        String[] sm2Keys = Sm2Util.getSm2Keys(false);
        String pubKey = sm2Keys[0];
        System.out.println("公钥:"+pubKey);
        String priKey = sm2Keys[1];
        System.out.println("私钥:"+priKey);

        // 国密加密
        String encrypt = Sm2Util.encrypt(pubKey, pwd);
        System.out.println("国密加密后密码:"+encrypt);

        // 国密解密
        String decrypt = Sm2Util.decrypt(priKey, encrypt);
        System.out.println("国密解密后密码:"+decrypt);

        // BC库加密
        String encrypt1 = Sm2Util.encrypt(pubKey, pwd, 1);
        System.out.println("BC加密:"+encrypt1);
        String decrypt1 = Sm2Util.decrypt(priKey, encrypt1, 1);
        System.out.println("BC解密:"+decrypt1);

    }
}

2.5 测试结果

未加密密码:123456
公钥:04bd133a440cd5ebaeeb68c958953a7794134c3992d2c3fd006571c7f1c7b3ebef484595ecd298d6c22fd1c0f84ba7ca8595761c271c959dc1370d7528c55b1ccb
私钥:835b53881c3e391ba430022119bf6b0f7fd7764ec9808d305ea5b620c531363e
国密加密后密码:04795bd0129b2b08891eb1b24567b5d026f3f56e42bee356dc120fc5bf699baac5b818ab2f3086791ee8bab8868a301e9e2b2884f2ef67ab6b615b6fe235f7c204ad520dfcd82c945420979d12accf014d4fe75724987b9ae8d96a5e1099af45b0ac970eceac9e
国密解密后密码:123456
BC加密:0464fcab91fa522f877f45c204e1043f3c9124d290f4b68c6c1bd5f420ce184c560d2654d781924b0d0d24affe32aac569f7c12a0c951e02478c50cf6e0bf241f5d225178c7c35a2cd5aa39d2381e27e74701b9c6efd439882775a33d1ce2367c51c2669f248d7
BC解密:123456

四、SM3在项目中具体使用

        使用hutool工具类

1. 依赖 pom.xml

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.4</version>
        </dependency>
        <!-- bcprov-jdk15to18 SM3-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15to18</artifactId>
            <version>1.69</version>
        </dependency>

2. 测试类 Sm3Test.java

@SpringBootTest
public class Sm3Test {

    @Test
    void encryTest(){
        String encryptStr = SmUtil.sm3("123");
        System.out.println("未加密的明文:123");
        System.out.println("SM3加密后的密文:"+encryptStr);
    }
}

3. 测试结果

未加密的明文:123
SM3加密后的密文:6e0f9e14344c5406a0cf5a3b4dfb665f87f4a771a31f7edbb5c72874a32b2957

借鉴博客:国产加密实际运用:使用SM3加盐存储密码,并且使用SM2进行登录认证_MrZhouGx的博客-CSDN博客_sm3 加盐文章来源地址https://www.toymoban.com/news/detail-457672.html

到了这里,关于国密算法SM2、SM3的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenSSL 3.1.1 ECC 加密、解密、签名、验签(国密 sm2、sm3)

    openssl 3 默认废弃了 旧版本 (opessl 1.x) 的部分api 导致部分旧ecc 代码无法使用(可以通过配置编译选项打开) ,这里展示如何使用新接口用ECC 进行加密解密。 新接口是真的方便,基本上你都不需要懂啥密码学知识,对我们这种密码白痴来说太好了 头文件 生成密钥对 导出公

    2024年02月05日
    浏览(61)
  • 国密算法概述、及算法的集成应用(sm2、sm3、sm4)

    由于项目的需求,需要集成国密加解密,于是对国密又温故知新了一遍。同时整理了一下国密的一些算法。 本文主要从国密相关算法的简介、应用系统的集成、工具类的封装等方面入手,对国密进行深入的学习。 为了保障商用密码的安全性,国家密码局制定了一系列密码标

    2024年02月14日
    浏览(72)
  • Go实现国密算法SM2、SM3、SM4

    SM2椭圆曲线公钥密码算法 Public key cryptographic algorithm SM2 based on elliptic curves 遵循的SM2标准号为: GM/T 0003.1-2012、GM/T 0003.2-2012、GM/T 0003.3-2012、GM/T 0003.4-2012、GM/T 0003.5-2012、GM/T 0009-2012、GM/T 0010-2012 依赖包: github.com/tjfoc/gmsm/sm2 SM3密码杂凑算法 - SM3 cryptographic hash algorithm 遵循的SM

    2024年02月15日
    浏览(48)
  • 国密算法:利用python进行sm2非对称算法的实现,国密算法库gmssl的使用

    我们继续来进行国密算法的演示。 本篇演示sm2非对称算法的实现,国密算法库gmssl的使用。 sm2: 即椭圆曲线公钥密码算法,是由国家密码管理局发布的; 非对称加密算法,即有一对不一样的密钥:公钥和私钥,公钥用来加密,私钥用来解密; 公钥和私钥:公钥,可以公开。

    2024年02月06日
    浏览(61)
  • java 国密算法工具类(支持SM2 SM3 SM4)

    前言 工具采用BC库实现,支持前后端加解密,前端建议使用sm-crypto 引入pom依赖 基本使用如下 国密SM2算法 国密SM3算法 国密SM4算法使用

    2024年02月13日
    浏览(51)
  • 4.Java开源RSA/SM2非对称加密算法对比介绍

    前期内容导读: Java开源RSA/AES/SHA1/PGP/SM2/SM3/SM4加密算法介绍 Java开源AES/SM4/3DES对称加密算法介绍及其实现 Java开源AES/SM4/3DES对称加密算法的验证说明 非对称加密 主要是指 秘钥对 是非对称的(相对于 对称加密 而言),简单理解就是加密秘钥和解密秘钥不同,一般叫做公钥和私

    2024年02月14日
    浏览(46)
  • 国密算法SM2,SM3,SM4-java实现原理

    SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法,基于ECC。其签名速度与秘钥生成速度都快于RSA,非对称加密,该算法已公开 SM3是中华人民共和国政府采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。SM3主要用数字签名及验证、消息认

    2024年02月13日
    浏览(39)
  • Python实现国家商用密码算法sm2/sm3/sm4/sm9(国密)

    2010 年开始,我国国家密码管理局就已经开始陆续发布了一系列国产加密算法,这其中就包括 SM1、SM2、SM3 、SM4、SM7、SM9、ZUC(祖冲之加密算法)等,SM 代表商密,即商业密码,是指用于商业的、不涉及国家秘密的密码技术。SM1 和 SM7 的算法不公开,其余算法都已成为 ISO/IEC

    2024年02月15日
    浏览(48)
  • 新手入门 | 掌握国密算法:新手指南: SM2 / SM3 / SM4密码算法详解

    在密码学领域,有多种加密与签名算法,它们在信息安全领域发挥着举足轻重的作用。如今,随着互联网的快速发展,网络安全已经成为各类信息系统完整性、可用性、保密性的重要保障,越来越多的国产密码算法得到了广泛的应用与关注。在本文中,我们将重点介绍三个经

    2024年02月12日
    浏览(157)
  • react+vue 前端国密算法sm2、sm3 、sm4的js ts实现

    1. 简单介绍下SM2 和 SM3 SM2 算法:是一种公钥加密算法,它的密钥长度为 256 位,安全性较高。可用于数字签名、密钥协商等场景。 SM3 算法:是一种对称加密算法,用于消息摘要和数字签名等场景。它的密钥长度为 256 位,安全性较高。SM3 算法与 SM2 算法相互配合,提高了整体

    2024年01月19日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包