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 相关文章推荐
windows下wxPython开发环境安装与配置方法
Jun 28 Python
python自然语言编码转换模块codecs介绍
Apr 08 Python
Python 性能优化技巧总结
Nov 01 Python
Python多进程fork()函数详解
Feb 22 Python
Python中super函数用法实例分析
Mar 18 Python
详解python读取和输出到txt
Mar 29 Python
Python lxml模块的基本使用方法分析
Dec 21 Python
Windows下python3安装tkinter的问题及解决方法
Jan 06 Python
python shell命令行中import多层目录下的模块操作
Mar 09 Python
python实现时间序列自相关图(acf)、偏自相关图(pacf)教程
Jun 03 Python
pandas中DataFrame数据合并连接(merge、join、concat)
May 30 Python
关于Python中进度条的六个实用技巧分享
Apr 05 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函数获取当前运行的环境 来进行判断执行逻辑(小技巧)
2013/06/25 PHP
php管理nginx虚拟主机shell脚本实例
2014/11/19 PHP
JS 继承实例分析
2008/11/04 Javascript
js读取注册表的键值示例
2013/09/25 Javascript
如何在指定的地方插入html内容和文本内容
2013/12/23 Javascript
html文档中的location对象属性理解及常见的用法
2014/08/13 Javascript
深入理解JavaScript系列(40):设计模式之组合模式详解
2015/03/04 Javascript
jQuery选择器源码解读(六):Sizzle选择器匹配逻辑分析
2015/03/31 Javascript
js插件YprogressBar实现漂亮的进度条效果
2015/04/20 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
js实现点击图片自动提交action的简单方法
2016/10/16 Javascript
Node.js开启Https的实践详解
2016/10/25 Javascript
简单实现Bootstrap标签页
2020/08/09 Javascript
vue.js与element-ui实现菜单树形结构的解决方法
2018/04/21 Javascript
jQuery实现简单复制json对象和json对象集合操作示例
2018/07/09 jQuery
Javascript实现时间倒计时功能
2018/11/17 Javascript
vue基于两个计算属性实现选中和全选功能示例
2019/02/08 Javascript
node.js使用express框架进行文件上传详解
2019/03/03 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
推荐11个实用Python库
2015/01/23 Python
django 使用 request 获取浏览器发送的参数示例代码
2018/06/11 Python
python监控进程状态,记录重启时间及进程号的实例
2019/07/15 Python
解决tensorflow添加ptb库的问题
2020/02/10 Python
浅谈keras中loss与val_loss的关系
2020/06/22 Python
python的flask框架难学吗
2020/07/31 Python
Electrolux伊莱克斯巴西商店:家用电器、小家电和配件
2018/05/23 全球购物
一些Unix笔试题和面试题
2013/01/22 面试题
市场营销调查计划书
2014/05/02 职场文书
重大事项社会稳定风险评估方案
2014/06/15 职场文书
车辆委托书范本
2014/10/05 职场文书
中班下学期幼儿评语
2014/12/30 职场文书
当幸福来敲门观后感
2015/06/01 职场文书
2016年大学生暑假爱心支教活动策划书
2015/11/26 职场文书
创业计划书之冷饮店
2019/09/27 职场文书
Java图书管理系统,课程设计必用(源码+文档)
2021/06/30 Java/Android
Go归并排序算法的实现方法
2022/04/06 Golang