区块链中的密码学之数字签名方案(十二)

1. 前言

类似在纸质合同上签名确认合同内容,数字签名用于证实某数字内容的完整性( integrity)和来源( 或不可抵赖,non-repudiation)。
一个典型的场景是,A 要发给 B 一个文件( 一份信息) ,B 如何获知所得到的文件即为 A 发出的原始版本?A 先对文件进行摘要,然后用自己的私钥进行加密,将文件和加密串都发给B。B 收到文件和加密串后,用 A 的公钥来解密加密串,得到原始的数字摘要,跟对文件进行摘要后的结果进行比对。如果一致,说明该文件确实是 A 发过来的,并且文件内容没有被修改过。

2. DSA

签名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应当为:g^s≡g^(x+k+H(m)) mod p=g^xg^kg^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;用户公钥为:随机选取x,计算公钥y = g^x mod p.

第二步,对每一个消息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;
  • w=s^-1 mod q
  • u1=H(m)*w mod q
  • u2=r*w mod q
  • v = (g^u1* y^u2 mod p) mod q
  • 判断v和r是否相等。

算法的正确性验证:

总结:

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

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

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

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

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

3. ECDSA

Parameter
CURVE the elliptic curve field and equation used
G elliptic curve base point, such as a pt {\displaystyle (x_{0},y_{0})} on {\displaystyle y^{2}=x^{3}+7}, a generator of the elliptic curve with large prime order n
n integer order of G, means that {\displaystyle n\times G=O}, where {\displaystyle O} is the identity element.

椭圆曲线签名算法原理,椭圆曲线签名算法,即ECDSA。
设私钥、公钥分别为k、K,即K = kG,其中G为G点。

签名过程如下:

  1. 选择一条椭圆曲线Ep(a,b),和基点G;

2、选择私有密钥k(k<n,n为G的阶),利用基点G计算公开密钥K=kG;

3、产生一个随机整数r(r<n),计算点R=rG;

4、将原数据和点R的坐标值x,y作为参数,计算SHA1做为hash,即Hash=SHA1(原数据,x,y);

5、计算s≡r - Hash * k (mod n)

6、r和s做为签名值,如果r和s其中一个为0,重新从第3步开始执行

验证过程如下:

1、接受方在收到消息(m)和签名值(r,s)后,进行以下运算

2、计算:sG+H(m)P=(x1,y1), r1≡ x1 mod p。

3、验证等式:r1 ≡ r mod p。

4、如果等式成立,接受签名,否则签名无效。

原理如下
hG/s + xK/s = hG/s + x(kG)/s = (h+xk)G/s = r(h+xk)G / (h+kx) = rG

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 椭圆曲线签名算法
 *
 * 速度快 强度高 签名短
 *
 * 实现方 JDK1.7/BC
 */

public class ECDSAUtil {

   private static String str = "hello";

   public static void main(String[] args) {
      jdkECDSA();
   }

   public static void jdkECDSA() {

      try {
         //第一步:初始化化秘钥组,生成ECDSA算法的公钥和私钥
         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
         keyPairGenerator.initialize(256);

         KeyPair keyPair = keyPairGenerator.generateKeyPair();
         ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
         ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
         System.out.println("PublicKey:"+ecPublicKey.toString());
         // 2.执行签名
         PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
         KeyFactory keyFactory = KeyFactory.getInstance("EC");

         PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
         Signature signature = Signature.getInstance("SHA1withECDSA");
         signature.initSign(privateKey);

         signature.update(str.getBytes());
         byte[] sign = signature.sign();
         System.out.println("signResult:"+sign.toString());

         //3.验证签名
         X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());
         keyFactory = KeyFactory.getInstance("EC");
         PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
         signature = Signature.getInstance("SHA1withECDSA");
         signature.initVerify(publicKey);
         signature.update(str.getBytes());

         boolean bool = signature.verify(sign);
         System.out.println(bool);

      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

4. HMAC

全称是 Hash-based Message Authentication Code,即“基于 Hash 的消息认证码”。基本过程为对某个消息,利用提前共享的对称密钥和 Hash 算法进行加密处理,得到 HMAC 值。该HMAC 值提供方可以证明自己拥有共享的对称密钥,并且消息自身可以利用 HMAC 确保未经篡改。
HMAC(K, H, Message)
其中,K 为提前共享的对称密钥,H 为提前商定的 Hash 算法( 一般为公认的经典算法) ,Message 为要处理的消息内容。如果不知道 K 和 H,则无法根据 Message 得到准确的HMAC 值。

HMAC 一般用于证明身份的场景,如 A、B 提前共享密钥,A 发送随机串给 B,B 对称加密处
理后把 HMAC 值发给 A,A 收到了自己再重新算一遍,只要相同说明对方确实是 B。

HMAC 主要问题是需要共享密钥。当密钥可能被多方拥有的场景下,无法证明消息确实来自某人( Non-repudiation) 。反之,如果采用非对称加密方式,则可以证明。

5. 盲签名

1983 年由 David Chaum 提出。签名者在无法看到原始内容的前提下对信息进行签名。

盲签名主要是为了实现防止追踪( unlinkability) ,签名者无法将签名内容和结果进行对应。典型的实现包括 RSA 盲签名)。

6. 多重签名

n 个持有人中,收集到至少 m 个 的签名,即认为合法,这种签名被称为多重签名。其中,n 是提供的公钥个数,m 是需要匹配公钥的最少的签名个数。

7. 群签名

1991 年由 Chaum 和 van Heyst 提出。群签名属于群体密码学的一个课题。

群签名有如下几个特点:只有群中成员能够代表群体签名( 群特性) ;接收者可以用公钥验证群签名( 验证简单性) ;接收者不能知道由群体中哪个成员所签( 无条件匿名保护) ;发生争议时,群体中的成员或可信赖机构可以识别签名者( 可追查性) 。

Desmedt 和 Frankel 在 1991 年提出了基于门限的群签名实现方案。在签名时,一个具有 n个成员的群体共用同一个公钥,签名时必须有 t 个成员参与才能产生一个合法的签名,t 称为门限或阈值。这样一个签名称为(n, t)不可抵赖群签名。

8. 环签名

环签名由 Rivest,shamir 和 Tauman 三位密码学家在 2001 年首次提出。环签名属于一种简化的群签名。

签名者首先选定一个临时的签名者集合,集合中包括签名者自身。然后签名者利用自己的私钥和签名集合中其他人的公钥就可以独立的产生签名,而无需他人的帮助。签名者集合中的其他成员可能并不知道自己被包含在其中。

原文地址:https://www.cnblogs.com/anapodoton/p/10686750.html

时间: 2024-10-02 06:13:11

区块链中的密码学之数字签名方案(十二)的相关文章

1.3.2 区块链中的密码学——Merkle 树

在计算机领域,Merkle树大多用来进行完整性验证处理.在处理完整性验证的应用场景中,特别是在分布式环境下进行这样的验证时,Merkle树会大大减少数据的传输量以及计算的复杂度. Merkle哈希树是一类基于哈希值的二叉树或多叉树,其叶子节点上的值通常为数据块的哈希值,而非叶子节点上的值是将该节点的所有子节点的组合结果的哈希值. 如下图所示为一个Merkle哈希树,节点A的值必须通过节点C.D上的值计算而得到.叶子节点C.D分别存储数据块001和002的哈希值,而非叶子节点A存储的是其子节点C.

区块链中的密码学(三)-椭圆曲线加密算法分析

在目前密码学的非对称加密算法中,RSA算法依然是一种主流,但是随着比特币中对于一种之前不太流行的算法:椭圆加密算法(ECC)的成功应用后,这种算法得到了很大的关注和普及.有一种说法是中本聪不信任RSA算法,认为美国人在其中留有后门,而据斯诺登的爆料也确实如此.相较RSA,ECC不仅在某种程度上杜绝所谓留有后门的情况,而且加密性能/安全性都有提高.本文就带大家一窥ECC算法的天地. 鉴于ECC算法对数学知识要求比较高,不像RSA依赖于中学数学的水平,ECC用到了许多<近世代数基础>,<初等

1.3.2 区块链中的密码学——椭圆曲线密码算法(ECC)

今天在学椭圆曲线密码(Elliptic Curve Cryptography,ECC)算法,自己手里缺少介绍该算法的专业书籍,故在网上查了很多博文与书籍,但是大多数博客写的真的是...你懂的...真不愧是 '天下文章一大抄' 啊! 雷同不说,关键是介绍的都不是很清楚,是我在阅读过程中.产生的很多疑问无法解决!例如:只来句'P+Q=R',但是为什么等于呢?是根据什么计算出来的呢? 后来查了好久,才发现:这是规定的.是定义!瞬间很是无语! 好了,不吐槽了,为了方便大家对椭圆曲线密码算法有系统的了解,

区块链中的密码学

区块链概念 区块:可以看做是一页一页的账单,上面记录若干条数据 区块链:可以看做是账本,里面按照时间顺序将若干个账单 每个区块中包含两个最重要的值,自己的hash值,和上一个区块的hash值 详解: 区块链是一串使用密码学方法相关联产生的数据块,每一个区块中包含上一个区块的hash值,用于验证其信息的有效性(防伪)和生成下一个区块 Hash算法 Hash算法:可以将任意数据 生成 固定长度的16进制字符串 常见算法:md5 , sha1 , sha256 , sha512等,都是摘要算法 密码学

区块链中的密码学之数字证书体系(十四)

1. 前言 数字证书用来证明某个公钥是谁的,并且内容是正确的. 对于非对称加密算法和数字签名来说,很重要的一点就是公钥的分发.一旦公钥被人替换( 典型的如中间人攻击) ,则整个安全体系将被破坏掉. 怎么确保一个公钥确实是某个人的原始公钥?这就需要数字证书机制. 顾名思义,数字证书就是像一个证书一样,证明信息的合法性.由证书认证机构( Certification Authority,CA) 来签发,权威的 CA 包括 verisign 等. 数字证书内容可能包括版本.序列号.签名算法类型.签发者信

区块链中的密码学之默克尔树(十五)

目录 1. 前言 2. 默克尔树 3. 布隆过滤器 什么情况下需要布隆过滤器? 常规思路 布隆过滤器介绍 布隆过滤器原理 布隆过滤器添加元素 布隆过滤器查询元素 4. 同态加密 4.1 概览:同态加密的概念 4.2 同态加密的定义.安全性和简单实例 5. 零知识证明 零知识证明的提出 零知识证明的形式化定义 零知识证明满足的性质 基本的零知识协议 非交互式零知识证明 零知识证明的应用 1. 前言 2. 默克尔树 默克尔树( 又叫哈希树) 是一种二叉树,由一个根节点.一组中间节点和一组叶节点组成.

1.3.1 区块链中的加密算法——Hash算法(更新)

为了为保证存储于区块链中的信息的安全与完整,区块链中使用了包含密码哈希函数和椭圆曲线公钥密码技术在内的大量的现代密码学技术,同时,这些密码学技术也被用于设计基于工作量证明的共识算法并识别用户. 在前边的文章中已经系统的讲述了密码学中的哈希算法,在本节,将会给大家介绍Hash算法在区块链中的应用! 概念回顾: 哈希函数:是一类数学函数,可以在有限合理的时间内,将任意长度的消息压缩为固定长度的二进制串,其输出值称为哈希值,也称为散列值. 以哈希函数为基础构造的哈希算法,在现代密码学中扮演着重要的角色

[老k说区块链]区块链中的共识(1)— 免信任的共识机制

老k,柏链道捷CTO.清华阿尔山区块链研究中心高级工程师,超过17年的系统软件开发经验,在操作系统.编译器.虚拟机和符号执行方面都有实战经验.主持开发多个开眼项目,目前主要从事区块链底层系统开发工作. 这个系列的文章主要谈一下我对区块链中的共识机制的理解,欢迎跟大家一起交流.探讨. 前言 当今区块链的概念和产业已经遍布神州大地,创业言必区块链,在各种咖啡厅中你都可以听到周围的人谈论区块链,大部分从业者对区块链技术的一个认识是它是一个分布式账本技术,更有些人说区块链是各种计算机技术的组合,如P2P

区块链中的RESTFUL链码调用API原理详解

本文适合于熟悉开源区块链技术Hyperledger Fabric,以及希望更高效地使用华为云区块链服务的读者.当然,也欢迎任何对区块链技术有兴趣的读者阅读本文,相信读者们都能从中受益. 2018年2月1日 华为云发布企业级区块链开放平台区块链服务BCS(Blockchain Service),是基于开源区块链技术和华为在分布式并行计算.数据管理.安全加密等核心技术领域多年积累基础上推出的企业级区块链云服务产品,旨在帮助各行业.企业在华为云上快速.高效的搭建企业级区块链行业方案和应用. 如前所述,