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 相关文章推荐
python 文件操作删除某行的实例
Sep 04 Python
python中闭包Closure函数作为返回值的方法示例
Dec 17 Python
浅谈Python使用Bottle来提供一个简单的web服务
Dec 27 Python
解决新django中的path不能使用正则表达式的问题
Dec 18 Python
python利用Opencv实现人脸识别功能
Apr 25 Python
Django文件存储 默认存储系统解析
Aug 02 Python
Python远程开发环境部署与调试过程图解
Dec 09 Python
Python 3 使用Pillow生成漂亮的分形树图片
Dec 24 Python
Django restful framework生成API文档过程详解
Nov 12 Python
python 实时调取摄像头的示例代码
Nov 25 Python
Python读取文件夹下的所有文件实例代码
Apr 02 Python
python opencv通过按键采集图片源码
May 20 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
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
深入PHP内存相关的功能特性详解
2013/06/08 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
基于js实现微信发送好友如何分享到朋友圈、微博
2015/11/30 Javascript
Javascript的表单验证-提交表单
2016/03/18 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
2016/06/01 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
2016/09/16 Javascript
angular和BootStrap3实现购物车功能
2017/01/25 Javascript
node.js操作MongoDB的实例详解
2017/10/11 Javascript
基于vue-cli创建的项目的目录结构及说明介绍
2017/11/23 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
VUEJS 2.0 子组件访问/调用父组件的实例
2018/02/10 Javascript
vue异步axios获取的数据渲染到页面的方法
2018/08/09 Javascript
jquery.pagination.js分页使用教程
2018/10/23 jQuery
优雅的在React项目中使用Redux的方法
2018/11/10 Javascript
js屏蔽退格键(backspace或者叫后退键与F5)
2019/02/10 Javascript
JS实现选项卡效果的代码实例
2019/05/20 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
详解Python中time()方法的使用的教程
2015/05/22 Python
Mac 上切换Python多版本
2017/06/17 Python
如何优雅地处理Django中的favicon.ico图标详解
2018/07/05 Python
Python实现对字典分别按键(key)和值(value)进行排序的方法分析
2018/12/19 Python
用python建立两个Y轴的XY曲线图方法
2019/07/08 Python
如何使用Flask-Migrate拓展数据库表结构
2019/07/24 Python
Python 过滤错误log并导出的实例
2019/12/26 Python
基于Python爬取51cto博客页面信息过程解析
2020/08/25 Python
H5 video poster属性设置视频封面的方法
2020/05/25 HTML / CSS
植村秀加拿大官网:Shu Uemura加拿大
2019/09/03 全球购物
介绍一下Linux文件的记录形式
2012/04/18 面试题
Linux不知道文件后缀名怎么判断文件类型
2014/08/21 面试题
人事专员岗位职责
2013/11/20 职场文书
爱国口号
2014/06/19 职场文书
科技工作者先进事迹
2014/08/16 职场文书
Keras多线程机制与flask多线程冲突的解决方案
2021/05/28 Python
Vue的生命周期一起来看看
2022/02/24 Vue.js