Python 实现国产SM3加密算法的示例代码


Posted in Python onSeptember 21, 2020

SM3是中华人民共和国政府采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。主要用于报告文件数字签名及验证。

Python3代码如下:

from math import ceil

##############################################################################
#
#              国产SM3加密算法
#
##############################################################################

IV = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e"
IV = int(IV.replace(" ", ""), 16)
a = []
for i in range(0, 8):
  a.append(0)
  a[i] = (IV >> ((7 - i) * 32)) & 0xFFFFFFFF
IV = a


def out_hex(list1):
  for i in list1:
    print("%08x" % i)
  print("\n")


def rotate_left(a, k):
  k = k % 32
  return ((a << k) & 0xFFFFFFFF) | ((a & 0xFFFFFFFF) >> (32 - k))


T_j = []
for i in range(0, 16):
  T_j.append(0)
  T_j[i] = 0x79cc4519
for i in range(16, 64):
  T_j.append(0)
  T_j[i] = 0x7a879d8a


def FF_j(X, Y, Z, j):
  if 0 <= j and j < 16:
    ret = X ^ Y ^ Z
  elif 16 <= j and j < 64:
    ret = (X & Y) | (X & Z) | (Y & Z)
  return ret


def GG_j(X, Y, Z, j):
  if 0 <= j and j < 16:
    ret = X ^ Y ^ Z
  elif 16 <= j and j < 64:
    # ret = (X | Y) & ((2 ** 32 - 1 - X) | Z)
    ret = (X & Y) | ((~ X) & Z)
  return ret


def P_0(X):
  return X ^ (rotate_left(X, 9)) ^ (rotate_left(X, 17))


def P_1(X):
  return X ^ (rotate_left(X, 15)) ^ (rotate_left(X, 23))


def CF(V_i, B_i):
  W = []
  for i in range(16):
    weight = 0x1000000
    data = 0
    for k in range(i * 4, (i + 1) * 4):
      data = data + B_i[k] * weight
      weight = int(weight / 0x100)
    W.append(data)

  for j in range(16, 68):
    W.append(0)
    W[j] = P_1(W[j - 16] ^ W[j - 9] ^ (rotate_left(W[j - 3], 15))) ^ (rotate_left(W[j - 13], 7)) ^ W[j - 6]
    str1 = "%08x" % W[j]
  W_1 = []
  for j in range(0, 64):
    W_1.append(0)
    W_1[j] = W[j] ^ W[j + 4]
    str1 = "%08x" % W_1[j]

  A, B, C, D, E, F, G, H = V_i
  """
  print "00",
  out_hex([A, B, C, D, E, F, G, H])
  """
  for j in range(0, 64):
    SS1 = rotate_left(((rotate_left(A, 12)) + E + (rotate_left(T_j[j], j))) & 0xFFFFFFFF, 7)
    SS2 = SS1 ^ (rotate_left(A, 12))
    TT1 = (FF_j(A, B, C, j) + D + SS2 + W_1[j]) & 0xFFFFFFFF
    TT2 = (GG_j(E, F, G, j) + H + SS1 + W[j]) & 0xFFFFFFFF
    D = C
    C = rotate_left(B, 9)
    B = A
    A = TT1
    H = G
    G = rotate_left(F, 19)
    F = E
    E = P_0(TT2)

    A = A & 0xFFFFFFFF
    B = B & 0xFFFFFFFF
    C = C & 0xFFFFFFFF
    D = D & 0xFFFFFFFF
    E = E & 0xFFFFFFFF
    F = F & 0xFFFFFFFF
    G = G & 0xFFFFFFFF
    H = H & 0xFFFFFFFF

  V_i_1 = []
  V_i_1.append(A ^ V_i[0])
  V_i_1.append(B ^ V_i[1])
  V_i_1.append(C ^ V_i[2])
  V_i_1.append(D ^ V_i[3])
  V_i_1.append(E ^ V_i[4])
  V_i_1.append(F ^ V_i[5])
  V_i_1.append(G ^ V_i[6])
  V_i_1.append(H ^ V_i[7])
  return V_i_1


def hash_msg(msg):
  # print(msg)
  len1 = len(msg)
  reserve1 = len1 % 64
  msg.append(0x80)
  reserve1 = reserve1 + 1
  # 56-64, add 64 byte
  range_end = 56
  if reserve1 > range_end:
    range_end = range_end + 64

  for i in range(reserve1, range_end):
    msg.append(0x00)

  bit_length = (len1) * 8
  bit_length_str = [bit_length % 0x100]
  for i in range(7):
    bit_length = int(bit_length / 0x100)
    bit_length_str.append(bit_length % 0x100)
  for i in range(8):
    msg.append(bit_length_str[7 - i])

  # print(msg)

  group_count = round(len(msg) / 64)

  B = []
  for i in range(0, group_count):
    B.append(msg[i * 64:(i + 1) * 64])

  V = []
  V.append(IV)
  for i in range(0, group_count):
    V.append(CF(V[i], B[i]))

  y = V[i + 1]
  result = ""
  for i in y:
    result = '%s%08x' % (result, i)
  return result


def str2byte(msg): # 字符串转换成byte数组
  ml = len(msg)
  msg_byte = []
  msg_bytearray = msg # 如果加密对象是字符串,则在此对msg做encode()编码即可,否则不编码
  for i in range(ml):
    msg_byte.append(msg_bytearray[i])
  return msg_byte


def byte2str(msg): # byte数组转字符串
  ml = len(msg)
  str1 = b""
  for i in range(ml):
    str1 += b'%c' % msg[i]
  return str1.decode('utf-8')


def hex2byte(msg): # 16进制字符串转换成byte数组
  ml = len(msg)
  if ml % 2 != 0:
    msg = '0' + msg
  ml = int(len(msg) / 2)
  msg_byte = []
  for i in range(ml):
    msg_byte.append(int(msg[i * 2:i * 2 + 2], 16))
  return msg_byte


def byte2hex(msg): # byte数组转换成16进制字符串
  ml = len(msg)
  hexstr = ""
  for i in range(ml):
    hexstr = hexstr + ('%02x' % msg[i])
  return hexstr


def KDF(Z, klen): # Z为16进制表示的比特串(str),klen为密钥长度(单位byte)
  klen = int(klen)
  ct = 0x00000001
  rcnt = ceil(klen / 32)
  Zin = hex2byte(Z)
  Ha = ""
  for i in range(int(rcnt)):
    msg = Zin + hex2byte('%08x' % ct)
    # print(msg)
    Ha = Ha + hash_msg(msg)
    # print(Ha)
    ct += 1
  return Ha[0: klen * 2]


def sm3_hash(msg, Hexstr=0):
  """
  封装方法,外部调用
  :param msg: 二进制流(如若需要传入字符串,则把str2byte方法里msg做encode()编码一下,否则不编码)
  :param Hexstr: 0
  :return: 64位SM3加密结果
  """
  if (Hexstr):
    msg_byte = hex2byte(msg)
  else:
    msg_byte = str2byte(msg)
  return hash_msg(msg_byte)


if __name__ == '__main__':
  print(sm3_hash(b'SM3Test'))# 打印结果:901053b4681483b737dd2dd9f9a7f56805aa1b03337f8c1abb763a96776b8905

以上就是Python 实现国产SM3加密算法的示例代码的详细内容,更多关于Python 实现国产SM3加密算法的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
使用PDB简单调试Python程序简明指南
Apr 25 Python
Python内建模块struct实例详解
Feb 02 Python
python PyTorch参数初始化和Finetune
Feb 11 Python
Python自定义线程类简单示例
Mar 23 Python
利用Python yagmail三行代码实现发送邮件
May 11 Python
python之消除前缀重命名的方法
Oct 21 Python
一文带你了解Python中的字符串是什么
Nov 20 Python
一文秒懂python读写csv xml json文件各种骚操作
Jul 04 Python
python3.6、opencv安装环境搭建过程(图文教程)
Nov 05 Python
python实现自动清理重复文件
Aug 24 Python
Python使用for生成列表实现过程解析
Sep 22 Python
Python+Appium实现自动化清理微信僵尸好友的方法
Feb 04 Python
python如何实现DES加密
Sep 21 #Python
如何从csv文件构建Tensorflow的数据集
Sep 21 #Python
python打包多类型文件的操作方法
Sep 21 #Python
python 星号(*)的多种用途
Sep 21 #Python
Python+Selenium随机生成手机验证码并检查页面上是否弹出重复手机号码提示框
Sep 21 #Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
Sep 21 #Python
python map比for循环快在哪
Sep 21 #Python
You might like
php in_array 函数使用说明与in_array需要注意的地方说明
2010/04/13 PHP
PHP实现多进程并行操作的详解(可做守护进程)
2013/06/18 PHP
php setcookie(name, value, expires, path, domain, secure) 参数详解
2013/06/28 PHP
php使用pack处理二进制文件的方法
2014/07/03 PHP
实现PHP中session存储及删除变量
2018/10/15 PHP
用js计算页面执行时间的函数
2006/12/07 Javascript
JQuery给元素绑定click事件多次执行的解决方法
2014/05/29 Javascript
JQuery实现当鼠标停留在某区域3秒后自动执行
2014/09/09 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
JavaScript+html5 canvas绘制的小人效果
2016/01/27 Javascript
jQuery 检查某个元素在页面上是否存在实例代码
2016/10/27 Javascript
JavaScript实现简单的双色球(实例讲解)
2017/07/31 Javascript
javascript使用substring实现的展开与收缩文字功能示例
2019/06/17 Javascript
在Vue.js中使用TypeScript的方法
2020/03/19 Javascript
[52:15]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS LGD-GAMING
2014/05/23 DOTA
python开发之函数定义实例分析
2015/11/12 Python
使用PyInstaller将python转成可执行文件exe笔记
2018/05/26 Python
python实现人民币大写转换
2018/06/20 Python
python爬取内容存入Excel实例
2019/02/20 Python
对Python中一维向量和一维向量转置相乘的方法详解
2019/08/26 Python
python nmap实现端口扫描器教程
2020/05/28 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
2019/10/18 Python
python flask中动态URL规则详解
2019/11/22 Python
在python里创建一个任务(Task)实例
2020/04/25 Python
python boto和boto3操作bucket的示例
2020/10/30 Python
美国卡车、吉普车和SUV零件网站:4 Wheel Parts
2016/11/24 全球购物
计算机网络专业个人的自我评价
2013/10/17 职场文书
幼儿园毕业教师感言
2014/02/21 职场文书
小学生国旗下演讲稿
2014/04/25 职场文书
求职信标题怎么写
2014/05/26 职场文书
应届生自荐信
2014/06/30 职场文书
学生上课看漫画的检讨书
2014/09/26 职场文书
实习协议书
2015/01/27 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
党员发展大会主持词
2015/07/03 职场文书
初二物理教学反思
2016/02/19 职场文书