欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

国密(GmSSL)算法 SM4 在 GCM 模式中的应用

最编程 2024-07-10 16:02:10
...

国密(GmSSL)算法SM4之GCM模式


文章目录

  • 国密(GmSSL)算法SM4之GCM模式
  • 前言
  • 一、概念
    • 1.初始向量(IV,Initialization Vector)
    • 2.初始向量(IV,Initialization Vector)
    • 3.附加消息(AAD,Additional Authenticated Data)
    • 4.认证标签
  • 二、实现思路
    • 1.加密
    • 2.解密
  • 总结


前言

本文将介绍如何使用java实现SM4算法的GCM模式加解密,并提供相应的代码示例。加解密底层实现基于gmssl c 实现,通过java native方式调用。参考关志老师的国密算法实现:https://github.com/guanzhi/GmSSL


一、概念

1.初始向量(IV,Initialization Vector)

SM4 GCM模式是一种加密算法和模式的组合。SM4是一种对称加密算法,也被称为国密算法,由中国国家密码管理局(State Cryptography Administration)发布。它是一种分组密码,每个分组的大小为128位。GCM(Galois/Counter Mode)是一种加密模式,用于将加密算法与消息认证码(MAC)相结合,以提供加密和完整性保护。
GCM(Galois/Counter Mode)是一种加密模式,它结合了CTR模式和GMAC(Galois Message Authentication Code)进行消息加密和认证,不需要进行加密块填充。在GCM模式中,使用CTR模式对消息进行加密,然后使用GMAC算法生成认证标签。
总体而言,SM4 GCM模式提供了一种安全的加密和认证机制,适用于保护数据的机密性和完整性。

2.初始向量(IV,Initialization Vector)

作用和MD5的“加盐”有些类似,目的是防止同样的明文块,始终加密成同样的密文块。

3.附加消息(AAD,Additional Authenticated Data)

附加消息(AAD,Additional Authenticated Data)是在加密算法中使用的一种输入类型。它是一些与加密数据相关但不需要加密的附加信息。附加消息不会被加密,但会与加密数据一起进行认证。
在GCM模式中,附加消息是可选的输入,用于提供额外的上下文信息。它可以包含与加密数据相关的任何元数据,如协议版本、会话标识符等。附加消息对于验证数据的完整性非常有用,因为它们会被包含在消息认证码(MAC)计算中。
需要注意的是,附加消息不会被加密,只会与加密数据一起进行认证。因此,附加消息不会对加密数据的保密性产生影响,只用于提供额外的认证信息。

4.认证标签

在SM4 GCM模式中,认证标签是由GMAC(Galois Message Authentication Code)算法生成的固定长度值。它用于验证加密数据的完整性和认证数据的真实性。

认证标签是通过将GMAC算法应用于加密数据以及其他参数(如随机数和相关数据)来计算得出的。它通常是一系列具有固定长度的比特,例如128比特或96比特。

接收加密数据的一方可以使用相同的参数和接收到的认证标签来验证数据在传输过程中是否被篡改。如果计算得出的认证标签与接收到的标签匹配,表示数据完整且真实。否则,表示数据可能已被修改或损坏。

二、实现思路

1.加密

代码如下(示例):

        String testStr="gmssl";
        byte[] palaintextByte=testStr.getBytes();
        int blockLength= (int)Math.ceil((palaintextByte.length+taglen)/(double)Sm4.BLOCK_SIZE);
        byte[] tempCiphertextByte=new byte[blockLength*Sm4.BLOCK_SIZE];
        int cipherlen;
        sm4gcm.init(key, iv, aad, taglen, true);
        cipherlen = sm4gcm.update(palaintextByte, 0, palaintextByte.length, tempCiphertextByte, 0);
        cipherlen += sm4gcm.doFinal(tempCiphertextByte, cipherlen);
        byte[] ciphertextByte = Arrays.copyOfRange(tempCiphertextByte,0,cipherlen);
        //System.out.println("ciphertext:"+HexUtil.byteToHex(ciphertextByte));
        Assert.assertNotNull("data is empty exception!",ciphertextByte);

"taglen"参数用于指定认证标签(authentication tag)的长度。认证标签是由GMAC算法生成的固定长度的值,用于验证加密数据的完整性和认证数据的真实性。 "taglen"参数决定了认证标签的长度,通常以比特(bits)为单位。较长的认证标签长度可以提供更高的安全性,但同时也会增加计算和存储的开销。

缓冲区块大小的长度设置为加密块大小的整数倍,并且大于明文长度+认证标签长度。


2.解密

代码如下(示例):

		String test_plaintext="gmssl";
        String test_hex_ciphertext="b4a20037dc223f3e3474304dbb464a86423fa6c6db";
        byte[] ciphertextByte=HexUtil.hexToByte(test_hex_ciphertext);
        byte[] tempPlaintextByte = new byte[ciphertextByte.length+taglen];
        sm4gcm.init(key, iv, aad, taglen, false);
        int plainlen = sm4gcm.update(ciphertextByte, 0, ciphertextByte.length, tempPlaintextByte, 0);
        plainlen += sm4gcm.doFinal(tempPlaintextByte, plainlen);
        byte[] plaintextByte = Arrays.copyOfRange(tempPlaintextByte,0,plainlen);
        String plaintext=new String(plaintextByte);

解密时明文大小与加密时缓冲区块大小基本一致。


总结

本文是国密算法java实现的一系列文章内容之一。欢迎各位家人们观赏并提供宝贵意见,如您对此文章感兴趣欢迎关注和交流。GmSSL密码库的Java语言封装