锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. SM3杂凑算法与实现

SM3杂凑算法与实现

0
  • 软件开发
  • 发布于 2024-09-29
  • 15 次阅读
黄健
黄健

一、实验目的

SM3 杂凑算法与实现

(1)理解 Hash 函数的计算原理和特点

(2)掌握 SM3 杂凑算法原理

(3)编程实现 SM3 杂凑算法


硬件:运行 Windows 操作系统的计算机

软件:Python

二、方案设计

背景

SM3 是我国采用的一种密码散列函数标准,由国家密码管理局于2010 年12 月17日发布。《SM3 密码杂凑算法》于2012 年发布为密码行业标准(GM/T 0004-2012),2016年发布为国家标准(GB/T 32905-2016)。2018 年10 月,含有我国《SM3 密码杂凑算法》的ISO/IEC 10118-3:2018《信息安全技术杂凑函数第3 部分:专用杂凑函数》第4 版由ISO 发布,《SM3 密码杂凑算法》正式称为国际标准。在商用密码体系中,SM3 主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开。据国家密码管理局表示,其安全性及效率与SHA-256 相当。在实现上,SM3 密码杂凑算法运算速率高、灵活灵用、支持跨平台的高效实现,具有较好的实现效能。

原理

1、术语与定义:

(1)比特串 bit string

由 0 和 1 组成的二进制数字序列。

(2)大端 big-endian

数据在内存中的一种表示格式,规定左边为高有效位,右边为低有效位。数的高阶字节放在存储器的低地址,数的低阶字节放在存储器的高地址。

(3)消息 message

任意有限长度的比特串。本文本中消息作为杂凑算法的输入数据。

(4)杂凑值 hash value

杂凑算法作用于消息后输出的特定长度的比特串。本文本中的杂凑值长度为 256 比 特。

(5)字 word

长度为 32 位的比特串

2、符号

3.常量与函数

4、算法描述


SM3 密码杂凑算法基于 Merkle-Damgard 结构,杂凑函数 H 可将一个任意有限比特长度的消息 m 压缩到某一固定长度为 n 比特的杂凑值 h,即

SM3 密码杂凑算法是对长度为的消息 m 进行填充和迭代压缩生成杂凑值,杂凑值的长度为 256 bit。 整个算法的执行过程可以概括为四个步骤:消息填充、消息扩展、迭代压缩、输出结果。

消息填充:

假设消息 m 的长度为1比特。首先将比特” 1"添加到消息的末尾,再添加 k 个” 0”,k 是满足
的最小的正整数。然后再添加一个 64 位的比特串,该比特串是长度
的二进制表示。填充后的消息 m′ 的比特长度为 512 的倍数。


消息扩展:

迭代压缩:
迭代过程

压缩函数

三、方案实现

1.流程图

图1 SM3算法实现流程图


2.主要函数

def pad_message(message):——实现消息填充。由于先添加1,对应于16进制即为\x80,再填0补全至448mod 512,最后在加入消息长度的2进制比特串。

def SM3_CF(V, B):——实现压缩迭代。初始V为IV默认值,每次返回与前一次V的级联结果。按照SM3的算法流程实现压缩和迭代,其中,消息扩展也在本环节中进行,

def or_16(A, B):——实现两个字符串按位与或,返回整数C。

def LS(X, n):——实现循环左移。将左右个移动,再连接起来,实现循环。

3.代码实现

import binascii
import re
# SM3的初始向量
IV = [
    0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600,
    0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E
]

# 布尔函数FFj


def FF(X, Y, Z, j):
    if j < 16:
        return X ^ Y ^ Z
    else:
        return (X & Y) | (X & Z) | (Y & Z)

# 置换函数


def P0(X):
    return X ^ LS(X, 9) ^ LS(X, 17)


def P1(X):
    return X ^ LS(X, 15) ^ LS(X, 23)

# 循环左移


def LS(X, n):
    return ((X << n) & 0xFFFFFFFF) | (X >> (32 - n))

# 布尔函数GGj


def GG(X, Y, Z, j):
    if j < 16:
        return X ^ Y ^ Z
    else:
        return (X & Y) | (~X & Z)

# 消息填充函数


def pad_message(message):
    mlen1 = len(message)
    mlen = mlen1
    message += b'\x80'
    mlen += 1
    while mlen % 64 != 56:
        message += b'\x00'
        mlen += 1
    message += (mlen1 * 8).to_bytes(8, 'big')
    return message

# SM3压缩函数


def SM3_CF(V, B, k):
    W = [0] * 68
    W_ = [0] * 64
    for i in range(16):
        W[i] = int.from_bytes(B[i*4:i*4+4], 'big')
    for i in range(16, 68):
        W[i] = P1(W[i-16] ^ W[i-9] ^ LS(W[i-3], 15)) ^ LS(W[i-13], 7) ^ W[i-6]
    for i in range(64):
        W_[i] = W[i] ^ W[i+4]
    for i in range(0, len(W), 4):
        print(' '.join(hex(value) for value in W[i:i+4]))

    A, B, C, D, E, F, G, H = V
    for i in range(64):
        SS1 = LS((LS(A, 12) + E + LS(T(i), i % 32)) & 0xFFFFFFFF, 7)
        SS2 = SS1 ^ LS(A, 12)
        TT1 = (FF(A, B, C, i) + D + SS2 + W_[i]) & 0xFFFFFFFF
        TT2 = (GG(E, F, G, i) + H + SS1 + W[i]) & 0xFFFFFFFF
        D = C
        C = LS(B, 9)
        B = A
        A = TT1
        H = G
        G = LS(F, 19)
        F = E
        E = P0(TT2)
        print(
            f"Step {i+1} - A: {A:08X}, B: {B:08X}, C: {C:08X}, D: {D:08X}, E: {E:08X}, F: {F:08X}, G: {G:08X}, H: {H:08X}")
    return A, B, C, D, E, F, G, H

# T函数


def T(j):
    if j < 16:
        return 0x79CC4519
    else:
        return 0x7A879D8A

# SM3哈希函数


def string_to_ascii(s):
    return [ord(c) for c in s]


def or_16(A, B):
    A = int(A, 16)
    B = int(B, 16)
    C = A ^ B
    C = '{:08x}'.format(C)
    return C
# SM3哈希函数


def SM3(message):
    ascii_values = string_to_ascii(message)
    message_bytes = bytes(ascii_values)
    padded_message = pad_message(message_bytes)
    result = ''
    for i in IV:
        result += '{:08x}'.format(i)
    V = IV.copy()
    for i in range(len(padded_message) // 64):
        B = padded_message[i*64:(i+1)*64]
        V = SM3_CF(V, B, i)
        hex_string1 = binascii.hexlify(B).decode()

        formatted_hex_string1 = re.sub(r'(.{8})', r'\1 ', hex_string1)
        print(
            f"Extended Message at Step {i+1}: {formatted_hex_string1}")
        all = ''
        for iii in V:
            all += '{:08x}'.format(iii)
        result = or_16(all, result)

    return result


# 示例
message = 'abc'
hash_value = SM3(message)
formatted_hex_string2 = re.sub(r'(.{8})', r'\1 ', hash_value)
print("Hash Value:", formatted_hex_string2)

四、数据分析

1. SM3执行结果

测试数据:abc

中间数据:

填充完的消息:

图 2 SM3算法 填充 后的消息 结果 图

扩展后的消息:

图 3 SM3算法扩展后的消息 结果 图

每一轮的V:

图 5 SM3算法中间数据V的数据结果图

杂凑值:

图 4 SM3算法 杂凑结果 图

符合测试样例,算法执行成功。

2.SM3的安全性分析

2.1 优势


高抗碰撞性:SM3算法经过严格的安全性分析和测试,具有较高的抗碰撞性和抗预处理性,能够有效地保护数据的完整性和真实性。这意味着已知一个哈希结果,构建出具有相同结果的输入数据的难度非常大。

与国际标准相当:SM3算法在结构上与SHA-256相似,但通过增加多种新的设计技术,使其在安全性和效率上具有优势。尽管SM3算法的字典库远小于SHA-256,但其破解难度更大,因此在实际应用中具有更高的安全性。

抵抗常见攻击:SM3算法被设计为能够抵抗各种常见的密码分析攻击,包括碰撞攻击和预像攻击。虽然某些版本的SM3算法可能存在漏洞,如原根攻击和伪碰撞攻击,但完整的SM3算法仍然具有非常高的安全性。

高于其他算法:SM3算法的安全性要高于MD5算法和SHA-1算法。这是因为这些算法已经被证明存在严重的安全缺陷,而SM3算法则在设计和实现上更加精细和安全。

广泛应用和认可:SM3算法已经被46类重要的经济行业规范所采纳,并且在数字认证、金融密码系统、国家电网、社会保障信息系统等领域得到了广泛应用。这进一步证明了其在实际应用中的高安全性和可靠性。

SM3算法在安全性方面表现优异,能够有效抵抗各种常见的密码分析攻击,并且在国际标准上具有相当的水平。其高抗碰撞性、高效性以及广泛的应用领域,使其成为一个值得信赖的密码学哈希函数。

2.2风险

SM3算法作为一种密码杂凑函数,自2012年发布为行业标准,并在2016年成为国家标准。然而,近年来对其安全性进行了深入研究,发现了一些潜在的漏洞。

2021年2月,蜚语安全在对客户产品进行安全代码审计时,发现其依赖的微信小程序sm-crypto 开源NodeJS国密算法库中的SM3算法实现存在问题。进一步的研究表明,对于带消息填充的29步SM3算法,可以通过中间相遇攻击技术进行原根攻击和伪碰撞攻击。具体来说,从第1步开始的带消息填充的29步SM3算法的原根攻击时间复杂度为2254,而伪碰撞攻击时间复杂度为2125。这说明该算法不能有效抵抗这些攻击。

长度扩展攻击是指针对某些允许包含额外信息的加密散列函数的攻击手段。对于满足以下条件的散列函数,都可以作为攻击对象:① 加密前将待加密的明文按一定规则填充到固定长度(例如512或1024比特)的倍数;② 按照该规则进行加密。虽然证据中没有直接提到SM3算法是否受到长度扩展攻击,但考虑到其设计特性,这种攻击可能也会影响SM3的安全性。

五、思考与总结


1.请简述SM3与MD5、SHA-1的异同。

答:

SM3、MD5和SHA-1均属于散列函数,它们的主要功能是接收任意长度的数据输入,并输出固定长度的散列值,这个散列值通常被称为"消息摘要”。这些算法广泛应用于数据完整性验证和密码学领域。

相同点:

数据完整性:三者都用于确保数据在传输或存储过程中未被篡改。

固定长度输出:不论输入数据的大小,输出的散列值长度是固定的。

雪崩效应:输入数据的任何微小变化都会导致输出散列值的巨大变化。

不可逆: 从散列值不能推导出原始输入数据。

不同点:

设计标准: SM3是中国国家密码管理局制定的密码散列算法标准,而MD5和SHA-1是由国际组织或标准制定。

安全性: MD5和SHA-1由于设计时间较早,已存在已知的安全问题和攻击方法,如碰撞攻击。SM3设计时考虑了这些安全问题,采用了更复杂的结构来提高抗攻击能力。

输出长度: MD5产生128位的散列值,SHA-1产生160位的散列值,而SM3产生256位的散列值,提供了更高的安全边际。

算法结构:SM3使用了更复杂的数学结构和算法流程,包括用于置乱消息的置换函数和用于压缩消息的布尔函数,这使得其对抵抗密码分析攻击更为强固。

2.实验过程中还遇到了什么问题,如何解决的?通过该实验有何收获?

答:

问题1:在消息填充模块,算法实现时将mlen用于直接累加计数,导致原数据长度丢失。

方案:设置一个变量,记录初始长度,在结尾将原mlen替换。

问题2:在得到V后,如何输出杂凑函数值,如何级联?

方案:属于概念未明晰,不知如何进行级联。第一轮的输出应该与初始向量IV级联,而后以此类推。而且,需要注意的是,在级联后,需要按位进行与或操作。

收获:

通过本次实验,我深入理解了SM3算法的原理和特点,尤其掌握了SM3算法的结构和实现方法,编程实践增强了我对该算法的理解并提升了我的技术能力,让我对密码学领域有了更深刻的认识。


原文链接: https://blog.csdn.net/m0_74985950/article/details/140408432

标签: #算法 139 #知识库 257
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.