Python realizes the national commercial encryption algorithm sm2/sm3/sm4/sm9 (national secret)

Since 2010, my country's National Cryptography Administration has successively released a series of domestic encryption algorithms, including SM1, SM2, SM3, SM4, SM7, SM9, ZUC (Zu Chong's encryption algorithm), etc. SM stands for business secret, That is, commercial encryption refers to encryption technology that is used for business and does not involve state secrets. Algorithms of SM1 and SM7 are not public, and other algorithms have become ISO/IEC international standards. At present, the SM2, SM3 and SM4 algorithms are widely used, and the usage of these three is different.

the difference

Encryption Algorithm definition Application field features similar algorithm Is it public
sm1 Symmetric encryption algorithm chip The packet length and key length are both 128 bits DES、3DES private
sm2 Asymmetric encryption algorithm data encryption ECC elliptic curve encryption mechanism 256 bits, faster processing speed and less consumption than RSA RSA、RSA4096 public
sm3 Hash function algorithm integrity check The security and efficiency of the hash algorithm are equivalent to SHA-256, and the compression function is more complex SHA1, SHA-256, SHA-384, SHA-512 public
sm4 Symmetric encryption algorithm Data encryption and LAN products The block length and key length are both 128 bits, and the number of calculation rounds is large DES、AES public
sm7 Symmetric encryption algorithm Contactless IC card The packet length and key length are both 128 bits private
sm9 Identity Encryption Algorithm (IBC) End-to-end offline secure communication The encryption strength is equivalent to the RSA encryption algorithm with a 3072-bit key public
ZUC Symmetric encryption algorithm Mobile communication, 4G network stream cipher public

SM2

Both the SM2 algorithm and the RSA algorithm are public-key cryptographic algorithms. The SM2 algorithm is a more advanced and secure algorithm that is used to replace the RSA algorithm in our country's commercial encryption system.
With the development of cryptography and computer technology, the currently commonly used 1024-bit RSA algorithm is facing serious security threats. After research, our national encryption management department decided to replace the RSA algorithm with the SM2 elliptic curve algorithm.
Introduction to the sequence of ciphertext data
The result of SM2 asymmetric encryption consists of three parts: C1, C2, and C3. Among them, C1 is the elliptic curve point calculated according to the generated random number, C2 is the ciphertext data, and C3 is the summary value of SM3. The results of the original national secret standard are stored in the order of C1, C2, and C3, and the new standard is stored in the order of C1, C3, and C2. Therefore, we have added a new ciphertext data order setting when doing SM2 encryption. , to be compatible with previous SM2 algorithm encryption.

import base64
import binascii
from gmssl import sm2, func


def test_sm2():
    private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
    public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'

    sm2_crypt = sm2.CryptSM2(
        public_key=public_key, private_key=private_key)
    data = b"111"
    enc_data = sm2_crypt.encrypt(data)
    #print("enc_data:%s" % enc_data)
    #print("enc_data_base64:%s" % base64.b64encode(bytes.fromhex(enc_data)))
    dec_data = sm2_crypt.decrypt(enc_data)
    print(b"dec_data:%s" % dec_data)
    assert data == dec_data

    print("-----------------test sign and verify---------------")
    random_hex_str = func.random_hex(sm2_crypt.para_len)
    sign = sm2_crypt.sign(data, random_hex_str)
    print('sign:%s' % sign)
    verify = sm2_crypt.verify(sign, data)
    print('verify:%s' % verify)
    assert verify

    
def test_sm2sm3():
     private_key = "3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8"
     public_key = "09F9DF311E5421A150DD7D161E4BC5C672179FAD1833FC076BB08FF356F35020"\
                  "CCEA490CE26775A52DC6EA718CC1AA600AED05FBF35E084A6632F6072DA9AD13"
     random_hex_str = "59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21"

     sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)
     data = b"message digest"

     print("-----------------test SM2withSM3 sign and verify---------------")
     sign = sm2_crypt.sign_with_sm3(data, random_hex_str)
     print('sign: %s' % sign)
     verify = sm2_crypt.verify_with_sm3(sign, data)
     print('verify: %s' % verify)
     assert verify


if __name__ == '__main__':
    test_sm2()
    test_sm2sm3()

SM3

SM3 National Secret Hash online tool. Support conventional character SM3 calculation, also support file SM3 calculation. The file does not need to be uploaded to the server, and there are no restrictions, and the SM3 hash value calculation can be completed in the browser. The encoding type (utf8/gbk etc.) only affects regular character SM3 calculations. For technical details related to SM3 national secrets, please refer to: "SM3 Password Hash Algorithm"

from gmssl import sm3, func

if __name__ == '__main__':
    y = sm3.sm3_hash(func.bytes_to_list(b"abc"))
    print(y)

SM4

SM4.0 (formerly known as SMS4.0) is a block cipher standard adopted by the government of the People's Republic of China and released by the State Encryption Administration on March 21, 2012. The relevant standard is "GM/T 0002-2012 "SM4 Block Cipher Algorithm" (formerly SMS4 Block Cipher Algorithm)".
In the commercial encryption system, SM4 is mainly used for data encryption. Its algorithm is public. The block length and key length are both 128bit. Both the encryption algorithm and the key expansion algorithm adopt a 32-round nonlinear iterative structure. Input 8 bit output.
The instruction length in SM4.0 is increased to a level greater than 64K (ie 64×1024), which is 128 times of the SM 3.0 specification (the rendering instruction length is allowed to be greater than 512).

from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT

key = b'3l5butlj26hvv313'
value = b'111'
iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
crypt_sm4 = CryptSM4()

crypt_sm4.set_key(key, SM4_ENCRYPT)
encrypt_value = crypt_sm4.crypt_ecb(value)
crypt_sm4.set_key(key, SM4_DECRYPT)
decrypt_value = crypt_sm4.crypt_ecb(encrypt_value)
assert value == decrypt_value

crypt_sm4.set_key(key, SM4_ENCRYPT)
encrypt_value = crypt_sm4.crypt_cbc(iv , value)
crypt_sm4.set_key(key, SM4_DECRYPT)
decrypt_value = crypt_sm4.crypt_cbc(iv , encrypt_value)
assert value == decrypt_value

SM9



from gmssl import sm9

if __name__ == '__main__':
    idA = 'a'
    idB = 'b'

    print ("-----------------test sign and verify---------------")
    
    master_public, master_secret = sm9.setup ('sign')

    Da = sm9.private_key_extract ('sign', master_public, master_secret, idA)
    
    message = 'abc'
    signature = sm9.sign (master_public, Da, message)

    assert (sm9.verify (master_public, idA, message, signature))

    print ("\t\t\t success")

    print ("-----------------test key agreement---------------")
    
    master_public, master_secret = sm9.setup ('keyagreement')

    Da = sm9.private_key_extract ('keyagreement', master_public, master_secret, idA)
    Db = sm9.private_key_extract ('keyagreement', master_public, master_secret, idB)

    xa, Ra = sm9.generate_ephemeral (master_public, idB)
    xb, Rb = sm9.generate_ephemeral (master_public, idA)

    ska = sm9.generate_session_key (idA, idB, Ra, Rb, Da, xa, master_public, 'A', 128)
    skb = sm9.generate_session_key (idA, idB, Ra, Rb, Db, xb, master_public, 'B', 128)

    assert (ska == skb)

    print ("\t\t\t success")
    
    print ("-----------------test encrypt and decrypt---------------")

    master_public, master_secret = sm9.setup ('encrypt')

    Da = sm9.private_key_extract ('encrypt', master_public, master_secret, idA)

    message = 'abc'
    ct = sm9.kem_dem_enc (master_public, idA, message, 32)
    pt = sm9.kem_dem_dec (master_public, idA, Da, ct, 32)

    assert (message == pt)

    print ("\t\t\t success")

reference

https://github.com/gongxian-ding/gmssl-python
https://github.com/duanhongyi/gmssl
https://www.lzltool.com/SM2

Guess you like

Origin blog.csdn.net/lilongsy/article/details/131678140