第2关:数字签名


任务描述

本关任务:对给定的身份以及消息进行数字签名。

相关知识

为了完成本关任务,你需要掌握:1.数字签名的概念和性质,2.公钥即身份。

数字签名的概念和性质

数字签名是密码学中的第二个重要部分。数字签名被认为是对纸上手写签名的数字模拟。我们对数字签名有两个特性要求,使其与我们对手写签名的预期一致。

  • 第一,只有你可以制作你自己的签名,但任何看到它的人都可以验证其有效性;
  • 第二,我们希望签名只与某一特定文件发生联系,因此该签名不能用于表明你同意或支持另一份不同的文件。

对于手写签名来说,第二条就如同确保别人不能将你的签名从一份文件上剪下来,贴到另一份文件的末尾那样。 那我们如何通过密码学来构建这些性质呢?首先,让我们把之前的直观讨论说得更具体一些,以便今后可以更好地论证数字签名方案,并讨论其安全特性。 数字签名方案

(1)数字签名方案由以下三个算法构成: ● (sk,pk):=generateKeys(keysize)``generateKeys方法把keysize作为输入,来产生一对公钥和私钥。私钥sk被安全保存,并用来签名一段消息;公钥pk是人人都可以找到的,拿到它,就可以用来验证你的签名。 ● sig:=sign(sk,message) 签名过程是把一段消息和私钥作为一个输入,对于消息输出是签名。 ●isValid:=verify(pk,message,sig) 验证过程是通过把一段消息和签名消息与公钥作为输入,如果返回的结果是真,证明签名属实;如果返回的结果为假,证明签名消息为假。 (2)我们要求以下两个性质有效: ● 有效签名可以通过验证,即: verify(pk,message,sign(sk,message))==true ● 签名不可伪造。

公钥即身份

让我们来看一下与数字签名并行的一个有用技巧,基本想法是从数字签名模式中拿出一个公共验证密钥,并将其与一个人或一个系统参与者的身份对等。如果你见到一条消息的签名被公钥pk正确验证,那么你可以认为pk就是在表达这条消息。你真的可以将公钥认为是参与者或者系统的一方,他可以通过签署声明而发布声明。从这个角度来说,公钥就是身份,让某人能为pk身份发声,他必须知道相应的密钥sk。 将公钥视为身份的一个结果是,你可以随时制定新的身份——你可以简单通过数字签名方案中的generateKeys程序,生成新的密钥对skpkpk是你可以使用的新的公共身份,sk是相应的密钥,只有你自己知道并可以让你代表身份为pk发声。在实践中,你可能会使用pk的哈希作为你的身份,这是因为公钥很大。如果是这样的话,为了验证消息来自你的身份,人们会需要验证:

  • (1)你的身份确实是pk的哈希;
  • (2)信息能经过公钥pk验证。

此外,在默认情况下,你的公钥pk基本上看起来是随机的,也并没有人能够通过检查pk发现你的现实身份(当然,一旦你开始使用这个身份发表声明,这些声明可能泄露信息,而让别人将你的真实身份与pk联系起来。我们很快会更详细地讨论这个问题)。你可以生成一个看起来随机的新身份,看起来像人群中的一张脸,但这些都只有你能够控制。

编程要求

根据提示,在右侧编辑器补充代码,根据公钥即身份,我们可以模拟一次消息签名,假如你的身份是e,有哈希函数H(x)=ax+b,那么我们可以把pk=H(e)作为公钥,sk=H(e)−1modq作为私钥,我们用私钥对消息m进行加密,即en(m)=sk∗m,那么我们解密就可以这样计算de(en(m))=en(m)∗pk。这里q保证是素数。 输入

 
  1. e a b q m

输出

 
  1. pk
  2. sk
  3. en(m)

输入

 
  1. 3 4 5 11 6

输出

 
  1. 17
  2. 2
  3. 12

提示: 费马定理求逆元,可以查询一下。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int e,a,b,q,m;
//在下面Begin和End之间补全代码
/*********** Begin ***********/
int quick(int x,int y)
{
    int ans=1;
    while(y)
    {
        if(y&1)
            ans=ans*x%q;
        x=x*x%q;
        y/=2;
    }
    return ans%q;
}
int main()
{
    cin>>e>>a>>b>>q>>m;
    int pk=a*e+b;
    int sk=quick(pk,q-2);
    int en=sk*m;
    cout<<pk<<endl<<sk<<endl<<en<<endl;
    return 0;
}
/*********** End ***********/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值