【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全

这篇具有很好参考价值的文章主要介绍了【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全
系列索引:【图解安全加密算法】加密算法系列索引 Python保姆级实现教程 | 物联网安全 | 信息安全

DSA数字签名算法基于SHA1哈希算法,关于SHA1的实现看另一篇文章。

一、什么是DSA

数字签名标准(DSS)由NIST公布,该标准能够使接收者能够验证数据的完整性和数据发送者的身份而制定,所采用的算法称为DSA算法,也称为DSA签名

二、DSA签名算法流程

【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全
DSA签名涉及四个参数,p,q,g,y和x,中前四者构成公钥,x为私钥(x<q)。

依据DSS标准,p为512~1024位,q是160位长的素数,且q|p-1;g=h(p-1)/q mod p,其中h是一整数,1<h<(p-1)且(h(p-1)/q mod p)>1;H(m)为参与签名的杂凑值,DSS选用SHA杂凑算法

(1)DSA 签名过程:

  用户随机选取k要求0<k<q,计算:

【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全

(2)DSA验证过程:

 接收者收到M,r,s后,首先验证0<r<q, 0<s<q,如果通过则计算:

【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全
如果v=r,则确认签名正确

三、具体实现过程(附代码)

我们实验要求参数可以设置成较小的,方便计算,如果大家严格按照算法参数要求设置需要改动。

(1)参数设置

算法的一些参数可以看要求设置成随机数,符合大小要求即可,我这里直接使用固定值先进行计算。
参数:
P、Q、H:人员输入,P要求是素数,512-1024位且位数L为64的倍数,Q为p-1的素因数比特长度160位,H是一个整数且1<H<p-1,并且要求g=h^(p-1)/q modp>1
X:(私钥)随机或伪随机整数,0<x<q,我这里设置成了75
K:随机数,0<k<q,我这里设置成了50

pqh = input("请输入P,Q,H的值:\n").split()
p, q, h = int(pqh[0]), int(pqh[1]), int(pqh[2])

g = int((h**(int((p-1)/q))) % p)

k = 50
x = 75
y = int(g**x % p)

print(f"P:{p},Q:{q},G:{g},x:{x},y:{y}")

(2)乘法逆元

乘法逆元:若存在正整数a,b,p, 满足ab = 1(mod p), 则称a 是b 的乘法逆元, 或称b 是a 的乘法逆元。
【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全

def EX_GCD(a, b, arr):  # 扩展欧几里得
    if b == 0:
        arr[0] = 1
        arr[1] = 0
        return a
    g = EX_GCD(b, a % b, arr)
    t = arr[0]
    arr[0] = arr[1]
    arr[1] = t - int(a / b) * arr[1]
    return g


def ModReverse(a, n):  # ax=1(mod n) 求a模n的乘法逆x
    arr = [0, 1, ]
    gcd = EX_GCD(a, n, arr)
    if gcd == 1:
        return (arr[0] % n + n) % n
    else:
        return -1

(3)签名

def sign(g, p, q, x, M):
    r = int((g**k % p) % q)
    s = int((ModReverse(k, q)*(M+x*r)) % q)
    print(f"签名为({r}, {s})")
    return r, s

(4)验证

def verify(g, p, q, y, M, r, s):
    w = int(ModReverse(s, q) % q)
    u1 = int((M*w) % q)
    u2 = int(r*w % q)
    v = int(((g**u1)*(y**u2) % p) % q)
    print(f"lc(w,u1,u2,v)=({w},{u1},{u2},{v})")
    if v == r:
        print("签名有效")
    else:
        print("签名无效")

四、跟着demo去debug

这里使用给出两组数据供大家调试,一组来源于课本,一组来源于网络。

(1)示例1:
【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全
【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全
(2)示例2:
【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全

五、完整代码

代码已补充,因为我们老师对参与运算的杂凑码要求只去前32位后右移八位参与运算,故代码中进行了处理,同时一些变量的取值可能不那么严谨,对于代码要求较高的大佬可以进行修改。代码未使用类进行封装,也是待完善的地方。

import random

A, B, C, D, E = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0  # 常量
K = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6]  # 常量

str = input("输入明文:\n").encode('utf-8')  # 这里对输入明文进行编码,str为bytes型
l = len(str)*8  # 每个字符8位
# python中二进制是字符串,不保留高位的0,这里使用zfill补高位0,如十进制6->110->0110,M这里是用了一个很长的字符串如:'11001010100011...'来表示原始数据
M = bin(int(str.hex(), 16))[2:].zfill(l)

# [可选项] 下面的函数仅仅显示输入明文的ascii,末尾为长度,该段显示的是补位后的
for i in range(64):
    if i < len(str):
        print(str[i], end=' ')
    elif i < len(str)+1:
        print('128', end=' ')
    elif i < 63:
        print('0', end=' ')
    else:
        print(l)

flag = 1  # 补1标志位,补一次1后置0
while len(M) % 512 != 448:
    if flag:
        M += '1'
        flag = 0
    else:
        M += '0'
M += "{:064b}".format(l)  # 末尾64位写入长度,空余补位补0
M = hex(int(M, 2))[2:]  # 这种转换会用到很多次,2进制转16进制,M现在是一个16进制字符串,如'1342a2c12...'
Mn = []  # 存储每个32位的字,因为M中一个字符4位(16进制),所以取M中的8个为一组,按要求将M分割成16个32位的字,故这里8*4=32,32*16=512
for i in range(16):
    Mn.append(M[8*i: 8*i+8])


def roll_left(num, k):
    """循环左移函数

    Parameters
    ----------
    num : int
        输入一个数字,2进制、10进制等均可
    k : int
        左移位数

    Returns
    -------
    int
        返回一个int结果
    """
    num_bin = bin(num)[2:].zfill(
        32)  # 因为python高位不会自动补0,导致要手动调整(也可能是我学艺不精),不然会忽略高位的0循环左移
    out = num_bin[k % len(num_bin):]+num_bin[:k % len(num_bin)]  # 注意预防溢出
    return int(out, 2)  # 二进制左移完成后转化成10进制输出


W = ['' for _ in range(80)]  # 存储80份扩展子明文
for i in range(80):
    if 16 <= i <= 79:
        # 16-79要进行异或运算,这里先转换成十进制(W中存的是16进制字符串,str无法运算)
        temp = int(W[i-3], 16) ^ int(W[i-8],
                                     16) ^ int(W[i-14], 16) ^ int(W[i-16], 16)

        W[i] = hex(roll_left(temp, 1))[2:].zfill(8)  # 循环左移1位
    else:
        W[i] = Mn[i]


def ft(b, c, d, t):
    """ft为逻辑函数

    Parameters
    ----------
    b : int
        B值
    c : int
        C值
    d : int
        D值
    t : int
        轮次

    Returns
    -------
    int
        运算结果
    """
    if t >= 0 and t <= 19:
        return ((b & c) | (~b & d))
    elif t >= 20 and t <= 39:
        return (b ^ c ^ d)
    elif t >= 40 and t <= 59:
        return ((b & c) | (b & d) | (d & c))
    elif t >= 60 and t <= 79:
        return (b ^ c ^ d)


Ap, Bp, Cp, Dp, Ep = A, B, C, D, E  # 暂存初始值
for t in range(80):
    tmp = B
    B = A
    A = ((((E + ft(tmp, C, D, t)) % (2**32)+roll_left(A, 5)) %
         (2**32)+int(W[t], 16)) % (2**32)+K[t//20]) % (2**32)  # 预防溢出进行取模运算
    E = D
    D = C
    C = roll_left(tmp, 30)

    #print(f" round{t+1} : {hex(A)} {hex(B)} {hex(C)} {hex(D)} {hex(E)}\n")
A, B, C, D, E = (Ap+A) % (2**32), (Bp+B) % (2**32), (Cp +
                                                     C) % (2**32), (Dp+D) % (2**32), (Ep+E) % (2**32)
# 相加运算,因为python不像c/c++可以使用unsigned char_32直接限制位数,因此要对位数进行限制
print("明文对应的杂凑码:\n", hex(A), hex(B), hex(C), hex(D), hex(E))

num_bin = bin(A)[2:].zfill(32)
out = '0'*8+num_bin[:-8 % len(num_bin)]
M = int(out, 2)

pqh = input("请输入P,Q,H的值:\n").split()
p, q, h = int(pqh[0]), int(pqh[1]), int(pqh[2])

g = int((h**(int((p-1)/q))) % p)

x = 75

y = int(g**x % p)
print(f"P:{p},Q:{q},G:{g},x:{x},y:{y}")

k = 50
print(f"用于签名的杂凑码为:{M}")


def EX_GCD(a, b, arr):  # 扩展欧几里得
    if b == 0:
        arr[0] = 1
        arr[1] = 0
        return a
    g = EX_GCD(b, a % b, arr)
    t = arr[0]
    arr[0] = arr[1]
    arr[1] = t - int(a / b) * arr[1]
    return g


def ModReverse(a, n):  # ax=1(mod n) 求a模n的乘法逆x
    arr = [0, 1, ]
    gcd = EX_GCD(a, n, arr)
    if gcd == 1:
        return (arr[0] % n + n) % n
    else:
        return -1


def sign(g, p, q, x, M):
    r = int((g**k % p) % q)
    s = int((ModReverse(k, q)*(M+x*r)) % q)
    print(f"签名为({r}, {s})")
    return r, s


def verify(g, p, q, y, M, r, s):
    w = int(ModReverse(s, q) % q)
    u1 = int((M*w) % q)
    u2 = int(r*w % q)
    v = int(((g**u1)*(y**u2) % p) % q)
    print(f"lc(w,u1,u2,v)=({w},{u1},{u2},{v})")
    if v == r:
        print("签名有效")
    else:
        print("签名无效")


r, s = sign(g, p, q, x, M)
verify(g, p, q, y, M, r, s)

图解安全加密算法系列持续更新,欢迎点赞收藏关注

上一篇:【图解AES加密算法】AES算法的Python实现 | Rijndael-128 | 对称加密 | 物联网安全
下一篇:【图解SHA1杂凑算法】SHA1杂凑算法的Python实现保姆级教程 | 物联网安全 | 信息安全

本人水平有限,文章中不足之处欢迎下方👇评论区批评指正~

如果感觉对你有帮助,点个赞👍 支持一下吧 ~

不定期分享 有趣、有料、有营养内容,欢迎 订阅关注 🤝 我的博客 ,期待在这与你相遇 ~文章来源地址https://www.toymoban.com/news/detail-463616.html

到了这里,关于【图解DSA数字签名算法】DSA签名算法的Python实现 | 物联网安全 | 信息安全的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 区块链中使用的加密算法和数字签名算法

    区块链中使用了多种加密算法和数字签名算法来确保数据的安全性、隐私性和可信性。以下是一些常见的加密算法和数字签名算法,它们在区块链技术中的应用: 哈希算法(Hash Functions) : 常见的哈希算法包括 SHA-256(Secure Hash Algorithm 256位)和 SHA-3(Keccak)等。 哈希算法用

    2024年02月04日
    浏览(52)
  • 算法2_非对称加密算法之ECDSA(椭圆曲线数字签名算法)

    ECDSA(椭圆曲线数字签名算法) AES(高级加密标准): =对称加密 ​ 对业务数据进行加密,防止他人可以看见 ECDSA(椭圆曲线数字签名算法):=非对称加密算法(公钥和私钥) ​ 验证数据的真实性,防止业务数据被篡改 SHA(安全哈希算法)=哈希算法 1. 作用: 因为ECDSA椭圆曲线数字签名算法获得

    2024年02月02日
    浏览(62)
  • 读改变未来的九大算法笔记05_数字签名

    3.3.1.1. 钟大小为11的乘法表 3.5.2.1. 欧几里得算法也能根据钥匙值计算出挂锁值,而这一算法要比暴力破解高效得多。这也是乘法方法被认为不安全的原因 4.2.1.1. 钟大小为22时n的三次方和七次方的值 4.5.1.1. 发明一种高效的分解因子算法只会破坏类RSA机制

    2024年02月08日
    浏览(46)
  • 密码学概念科普(加密算法、数字签名、散列函数、HMAC)

    密码散列函数 (Cryptographic hash function),是一个单向函数,输入消息,输出摘要。主要特点是: 只能根据消息计算摘要,很难根据摘要反推消息 改变消息,摘要一定会跟着改变 对于不同的消息,计算出的摘要几乎不可能相同 根据散列函数的上述特点,可以应用在保存密码、数

    2024年02月10日
    浏览(55)
  • 密码学学习笔记(十七 ):Edwards曲线数字签名算法 - edDSA

    Edwards曲线数字签名算法(Edwards-curve Digital Signature Alogorithm, edDSA)由Daniel J. Bernstein等人在2011年提出,它是一种使用基于扭曲爱德华兹曲线的Schnorr签名变体的数字签名方案。 EdDSA的一个特殊之处在于,该方案不要求每次签名都是用全新的随机数,而且该算法是确定性的。 EdDSA不直

    2024年02月16日
    浏览(48)
  • SM2椭圆曲线公钥密码算法--密钥对与数字签名

    SM2算法全称是SM2椭圆曲线公钥密码算法(SM是商用密码的拼音缩写),是一种基于“椭圆曲线”的密码ECC(Elliptic Curve Cryptography)。2016年,SM2成为中国国家密码标准。 在商用密码体系中,SM2主要用于替换RSA加密算法。 SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于

    2024年02月11日
    浏览(46)
  • Web应用JSON数据保护(密码算法、密钥、数字签名和数据加密)

    1.JSON(JavaScript Object Notation) JSON是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。JSON通过简单的key-value键值对来描述数据,可以被广泛用于网络通信、数据存储等各种应用场景,被广泛应用于互联网前后端数据交互与传输之中。 例如,

    2024年03月23日
    浏览(42)
  • 区块链数字签名、验签,以及椭圆曲线算法JS库—elliptic的使用

    目录 一、简介 二、椭圆曲线密码elliptic 1、安装elliptic和js-sha3 2、Keccak256 3、签名过程

    2024年02月02日
    浏览(46)
  • 基于AES的CMAC算法、MAC、Hash、数字签名之间的关系

    采用AES加密算法,使用密钥K,对明文P进行加密,得到的密文C,作为明文P的认证码,和明文P一起传输给接收方。接收方收到后,再使用自己的密钥,对明文再做一次AES加密,生成新的认证码,与接收到的发送方的认证码进行对比验证。如果相等,说明明文没有被篡改,接收

    2024年02月17日
    浏览(40)
  • 商用密码应用与安全性评估要点笔记(SM9数字签名算法)

    1、SM9标识密码算法简介         首先有几个概念需要弄清楚:         (1)标识identity,可以唯一确定一个实体身份的信息,且实体无法否认。比如身份证号、手机号、邮箱等。         (2)主密钥master key MK,密码分层结构中最顶层的密钥,这里是非对称密钥就包括主私

    2024年02月05日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包