zoukankan      html  css  js  c++  java
  • 区块链中的密码学之数字签名方案(十二)

    前言

    签名s应当是秘密数字x,消息的哈希值H(m)和随机数字k的一个函数。s=f(x,H(m),k)

    我们如何在不知道x和k的情况下验证该等式呢。

    我们可以借助于上章学习的离散对数问题。y=g^x mod p 和r=g^k mod p发送给接受者,不用担心x和k的泄露。一般称x为私钥,y为公钥,<r,s>为数字签名。

    签名关系F和签名函数f是等价的,而验签关系G是由F决定的。因此关系F是决定签名方案的关键。

    我们最容易想到的一种方案是让 中各数字之间有加法运算,如:

    s=x+k+H(m)mod(p-1)

    所以,G应当为:gs≡g(x+k+H(m)) mod p=gxgk*g^H(m) mod p≡yr * g^H(m) mod p

    所以,接收方需要验证关系:g^s≡yr * g^H(m) mod p是否成立就可以验证签名了。

    但是目前仍然存在问题,即正常的签名是可以通过验证的啊,但是可能被攻击者进行攻击。攻击者很容易在不知晓x和k的情况下,伪造签名r和s。

    那么如何进行伪造呢?

    攻击者只要先对s任取一值s’,然后通过解方程g^s≡yr * g^H(m) mod p,得到r'≡g^s'/(y * g^H(m)) mod p。

    显然满足上述公式的r'和s'也可以验证通过。

    所以我们必须修改方案,可以借助上面学习的离散对数问题,可以让验签方案中的s和都出现在指数上,这样攻击者就必须解决离散对数问题,才可能实施攻击。所以我们需要调整验签方案G和签名方案F。

    我们可以将签名关系F修改为:sk≡H(m)+xr (mod (p-1)),则签名函数s为s=(H(m)+xr) /k mod(p-1),即k=(H(m)+xr) /s mod(p-1),所以有:r=g^k mod p=g^(H(m)+xr)/s mod p=g^(H(m))/s * g^(r/s) mod p

    在该等式的结果中,仅包含签名<r,s>,公钥y和消息m,不会泄露私钥x,k。所以可以使用该等式作为验签关系:

    G:r=g^(H(m))/s * g^(r/s) mod p由于r和s都在指数上,所以攻击者无法伪造签名。

    总计一下,我们的DSA的签名方案为:

    r=g^k mod p;

    s=(H(m)+xr) /k mod(p-1)

    验签方案为:

    r=g^(H(m))/s * g^(r/s) mod p

    事实上,上面的方案还是存在着不足,即为了防止离散对数数学问题不被暴力破解,通常素数p的值需要很大,为了减小数字签名的规模,我们需要采取一定的措施:

    选择一个相对较小的整数q,使q满足g^q mod p=1,如果 p取1024比特,那么q就取160比特。

    这样,s和q修改为相同的规模,r的大小不变。所以我们需要把r缩减为同等规模。即r修改为

    r= (g^(H(m)/s * y^(r/s) mod p)) mod q;

    到此,我们总结下,DSA的签名方案为:

    签名过程:

    第一步,生成参数素数p,素数q,底数 g,满足g^q mod p=1;

    第二步,对任意消息m,生成随机数 k,1<k<q;

    第三步,计算r=(g^k mod p) mod p,若r=0,重复该步骤;

    第四步,计算s=(H(m)+xr)/k mod q,若 s=0,重复该步骤;

    第五步,令<r,s>为数字签名。

    验证过程:

    检查该过程是否成立:

    • 0<r<q;
    • 0<s<q;
    • r=(g^(H(m)/s) * y^(r/s) mod p) mod q;

    总结:

    第一,为了防止泄露私钥 ,只能公开公钥 ;

    第二,为了防止伪造签名,必须在验签方案中让签名出现在指数上;

    第三,为了减小数字签名规模,为指数选择一个相对较小的模数。

    而这一切都建立在素数域GF(p)中的整数加法、乘法、幂和离散对数的运算性质上。

    如果将素数域更换为有限域上的椭圆曲线,运算的对象变为椭圆曲线上的点,那么仍然可以定义出具有类似性质的加法、乘法。参照我们的DSA探秘之路,你自己就可以设计出具有更高安全性的椭圆曲线数字签名方案ECDSA,而ECDSA正是比特币体系使用的数字签名方案。

  • 相关阅读:
    三元表达式 列表和字典推导式 函数对象 名称空间 作用域 global和nonlocal 函数装饰器 枚举对象
    函数参数 打散机制 字符串比较 返回值
    函数简介
    三种字符串的介绍 文件的读写
    字符编码
    数据类型及其常用方法 数据类型转换 可变与不可变 值拷贝与深浅拷贝
    流程控制 while和for循环
    变量命名规范 常量 输入和输出 注释 数据类型 运算符 逻辑运算符
    语言分类 编译型和解释型语言分析 环境变量 代码执行的方式 pip介绍 变量
    Python django tests
  • 原文地址:https://www.cnblogs.com/hjs-junyu/p/10626744.html
Copyright © 2011-2022 走看看