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 中字典嵌套列表的方法
Jul 03 Python
python生成1行四列全2矩阵的方法
Aug 04 Python
python框架中flask知识点总结
Aug 17 Python
Python二叉搜索树与双向链表转换算法示例
Mar 02 Python
django配置连接数据库及原生sql语句的使用方法
Mar 03 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
Aug 04 Python
Python文件操作方法详解
Feb 09 Python
python代码中怎么换行
Jun 17 Python
Pycharm制作搞怪弹窗的实现代码
Feb 19 Python
matplotlib bar()实现多组数据并列柱状图通用简便创建方法
Feb 24 Python
彻底解决pip下载pytorch慢的问题方法
Mar 01 Python
python使用pywinauto驱动微信客户端实现公众号爬虫
May 19 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下利用header()函数设置浏览器缓存的代码
2010/09/01 PHP
遭遇php的in_array低性能问题
2013/09/17 PHP
php实现12306余票查询、价格查询示例
2014/04/17 PHP
php中socket通信机制实例详解
2015/01/03 PHP
PHP的关于变量和日期处理的一些面试题目整理
2015/08/10 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
删除重复数据的算法
2006/11/23 Javascript
jQuery基本过滤选择器使用介绍
2013/04/18 Javascript
Jquery实现的角色左右选择特效
2014/05/21 Javascript
Jquery焦点图实例代码
2014/11/25 Javascript
使用jquery菜单插件HoverTree仿京东无限级菜单
2014/12/18 Javascript
EasyUI中combobox默认值注意事项
2015/03/01 Javascript
jQuery实现拖拽效果插件的方法
2015/03/23 Javascript
jquery实现简单实用的打分程序实例
2015/07/23 Javascript
Js制作点击输入框时默认文字消失的效果
2015/09/05 Javascript
BootStrap iCheck插件全选与获取value值的解决方法
2016/08/24 Javascript
Angularjs通过指令监听ng-repeat渲染完成后执行脚本的方法
2016/12/31 Javascript
ReactNative页面跳转Navigator实现的示例代码
2017/08/02 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
2018/01/18 Javascript
NodeJs之word文件生成与解析的实现代码
2019/04/01 NodeJs
如何在vue中使用HTML 5 拖放API
2021/01/14 Vue.js
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
构建Python包的五个简单准则简介
2015/06/15 Python
Python实现简单HTML表格解析的方法
2015/06/15 Python
恢复百度云盘本地误删的文件脚本(简单方法)
2017/10/21 Python
Python中optparser库用法实例详解
2018/01/26 Python
Python将主机名转换为IP地址的方法
2019/08/14 Python
python+selenium select下拉选择框定位处理方法
2019/08/24 Python
python 负数取模运算实例
2020/06/03 Python
Python内存泄漏和内存溢出的解决方案
2020/09/26 Python
CSS3 3D制作实战案例分析
2016/09/18 HTML / CSS
Gweniss格温妮丝女包官网:英国纯手工制造潮流包包品牌
2018/02/07 全球购物
办公室主任主任岗位责任制
2014/02/11 职场文书
幼儿园欢迎词范文
2015/01/26 职场文书
天鹅湖观后感
2015/06/09 职场文书
会计主管竞聘书
2015/09/15 职场文书