Desde 2010, a Administração Nacional de Criptografia do meu país lançou sucessivamente uma série de algoritmos de criptografia domésticos, incluindo SM1, SM2, SM3, SM4, SM7, SM9, ZUC (algoritmo de criptografia de Zu Chong), etc. SM significa segredo comercial, isto é, criptografia comercial refere-se à tecnologia de criptografia usada para negócios e não envolve segredos de estado. Os algoritmos de SM1 e SM7 não são públicos e outros algoritmos tornaram-se padrões internacionais ISO/IEC. Atualmente, os algoritmos SM2, SM3 e SM4 são amplamente utilizados, e o uso desses três é diferente.
a diferença
Algoritmo de criptografia | definição | Campo de aplicação | características | algoritmo semelhante | é público |
---|---|---|---|---|---|
sm1 | Algoritmo de criptografia simétrica | lasca | O comprimento do pacote e o comprimento da chave são ambos de 128 bits | DES、3DES | privado |
sm2 | Algoritmo de criptografia assimétrica | criptografia de dados | Mecanismo de criptografia de curva elíptica ECC 256 bits, velocidade de processamento mais rápida e menor consumo que o RSA | RSA, RSA4096 | público |
sm3 | Algoritmo de função hash | verificação de integridade | A segurança e a eficiência do algoritmo de hash são equivalentes ao SHA-256 e a função de compactação é mais complexa | SHA1, SHA-256, SHA-384, SHA-512 | público |
sm4 | Algoritmo de criptografia simétrica | Criptografia de dados e produtos LAN | O comprimento do bloco e o comprimento da chave são ambos de 128 bits, e o número de rodadas de cálculo é grande | DES、AES | público |
sm7 | Algoritmo de criptografia simétrica | Cartão IC sem contato | O comprimento do pacote e o comprimento da chave são ambos de 128 bits | privado | |
sm9 | Algoritmo de Criptografia de Identidade (IBC) | Comunicação segura off-line de ponta a ponta | A força da criptografia é equivalente ao algoritmo de criptografia RSA com uma chave de 3072 bits | público | |
ZUC | Algoritmo de criptografia simétrica | Comunicação móvel, rede 4G | cifra de fluxo | público |
SM2
Tanto o algoritmo SM2 quanto o algoritmo RSA são algoritmos criptográficos de chave pública.O algoritmo SM2 é um algoritmo mais avançado e seguro usado para substituir o algoritmo RSA em nosso sistema nacional de criptografia comercial.
Com o desenvolvimento da criptografia e da tecnologia de computador, o algoritmo RSA de 1024 bits atualmente comumente usado está enfrentando sérias ameaças à segurança. Após pesquisas, nosso departamento nacional de gerenciamento de criptografia decidiu substituir o algoritmo RSA pelo algoritmo de curva elíptica SM2.
Introdução à sequência de dados do texto cifrado
O resultado da criptografia assimétrica SM2 consiste em três partes: C1, C2 e C3. Entre eles, C1 é o ponto da curva elíptica calculado de acordo com o número aleatório gerado, C2 são os dados do texto cifrado e C3 é o valor resumido de SM3. Os resultados do padrão de segredo nacional original são armazenados na ordem de C1, C2 e C3, e o novo padrão é armazenado na ordem de C1, C3 e C2. Portanto, adicionamos uma nova configuração de ordem de dados de texto cifrado quando fazendo criptografia SM2. , para ser compatível com a criptografia de algoritmo SM2 anterior.
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
Ferramenta online SM3 National Secret Hash. Suporta cálculo SM3 de caracteres convencionais, também suporta cálculo de arquivo SM3. O arquivo não precisa ser carregado no servidor e não há restrições, e o cálculo do valor de hash SM3 pode ser concluído no navegador. O tipo de codificação (utf8/gbk etc.) afeta apenas os cálculos SM3 de caracteres regulares. Para obter detalhes técnicos relacionados aos segredos nacionais SM3, consulte: "Algoritmo Hash de Senha SM3"
from gmssl import sm3, func
if __name__ == '__main__':
y = sm3.sm3_hash(func.bytes_to_list(b"abc"))
print(y)
SM4
SM4.0 (anteriormente conhecido como SMS4.0) é um padrão de cifra de bloco adotado pelo governo da República Popular da China e lançado pela State Encryption Administration em 21 de março de 2012. O padrão relevante é "GM/T 0002-2012 "SM4 Block Cipher Algorithm" (anteriormente SMS4 Block Cipher Algorithm)".
No sistema de criptografia comercial, SM4 é usado principalmente para criptografia de dados. Seu algoritmo é público. O comprimento do bloco e o comprimento da chave são ambos de 128 bits. Tanto o algoritmo de criptografia quanto o algoritmo de expansão de chave adotam uma estrutura iterativa não linear de 32 rodadas. Entrada de 8 bits saída.
O comprimento da instrução no SM4.0 é aumentado para um nível superior a 64K (ou seja, 64×1024), que é 128 vezes maior que a especificação do SM 3.0 (o comprimento da instrução de renderização pode ser superior a 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")
referência
https://github.com/gongxian-ding/gmssl-python
https://github.com/duanhongyi/gmssl
https://www.lzltool.com/SM2