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 相关文章推荐
python3图片转换二进制存入mysql
Dec 06 Python
tensorflow实现KNN识别MNIST
Mar 12 Python
Python3.遍历某文件夹提取特定文件名的实例
Apr 26 Python
python读取excel指定列数据并写入到新的excel方法
Jul 10 Python
Django 中使用流响应处理视频的方法
Jul 20 Python
flask框架中勾子函数的使用详解
Aug 01 Python
python字典一键多值实例代码分享
Jun 14 Python
Python实现FLV视频拼接功能
Jan 21 Python
pycharm部署、配置anaconda环境的教程
Mar 24 Python
OpenCV+python实现膨胀和腐蚀的示例
Dec 21 Python
Python基础之操作MySQL数据库
May 06 Python
PYTHON基于Pyecharts绘制常见的直角坐标系图表
Apr 28 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判断函数是否被定义的方法
2019/06/21 PHP
JS+CSS 制作的超级简单的下拉菜单附图
2013/11/22 Javascript
js查找某元素中的所有图片地址的方法
2014/01/16 Javascript
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
使用delegate方法为一个tr标签加一个链接
2014/06/27 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
2014/10/10 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
JS非Alert实现网页右下角“未读信息”效果弹窗
2015/09/26 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
微信小程序之仿微信漂流瓶实例
2016/12/09 Javascript
浅谈vue引入css,less遇到的坑和解决方法
2018/01/20 Javascript
浅谈Vue响应式(数组变异方法)
2018/05/07 Javascript
vue translate peoject实现在线翻译功能【新手必看】
2018/06/07 Javascript
JavaScript中 ES6变量的结构赋值
2018/07/10 Javascript
vue实现的仿淘宝购物车功能详解
2019/01/27 Javascript
浅谈vue中组件绑定事件时是否加.native
2019/11/09 Javascript
使用Vue生成动态表单
2019/11/26 Javascript
JS实现横向轮播图(中级版)
2020/01/18 Javascript
八大排序算法的Python实现
2021/01/28 Python
python队列Queue的详解
2019/05/10 Python
详解pytorch 0.4.0迁移指南
2019/06/16 Python
Django如何实现网站注册用户邮箱验证功能
2019/08/14 Python
python实现微信小程序用户登录、模板推送
2019/08/28 Python
tensorflow求导和梯度计算实例
2020/01/23 Python
Python matplotlib画图时图例说明(legend)放到图像外侧详解
2020/05/16 Python
详解python模块pychartdir安装及导入问题
2020/10/22 Python
欧洲最大的滑雪假期供应商之一:Sunweb Holidays
2018/01/06 全球购物
大学四年学习的自我评价分享
2013/12/09 职场文书
中学生期末评语
2014/02/03 职场文书
高中微机老师自我鉴定
2014/02/16 职场文书
党支部承诺书范文
2014/03/28 职场文书
合作意向书格式及范文
2014/03/31 职场文书
责任担保书范文
2014/05/21 职场文书
观看《周恩来的四个昼夜》思想汇报
2014/09/12 职场文书
创业计划书之DIY自助厨房
2019/09/06 职场文书
JavaScript的function函数详细介绍
2021/11/20 Javascript