Cryptography 如何确保某人没有使用公钥生成签名

Cryptography 如何确保某人没有使用公钥生成签名,cryptography,digital-signature,public,private-key,Cryptography,Digital Signature,Public,Private Key,我遵照这些指示。我的问题是-如何知道某个恶意代理没有编写恶意消息,然后使用我的公钥生成签名?例如: 鲍勃有他的私钥 Eve向Alice发送一条消息,并使用Bob的公钥计算“确认” Alice收到消息和Bob的公钥,计算确认==签名=>消息由Bob发送(?) 它与Bob发送消息和使用私钥计算的签名有何不同 编辑 privatekey=(95,49)#鲍勃的私钥 公钥=(95,25)#Bob的公钥 message=122#Eve写了一条恶意的消息 散列=消息**65537%2**8#Eve计算散列

我遵照这些指示。我的问题是-如何知道某个恶意代理没有编写恶意消息,然后使用我的公钥生成签名?例如:

  • 鲍勃有他的私钥
  • Eve向Alice发送一条消息,并使用Bob的公钥计算“确认”
  • Alice收到消息和Bob的公钥,计算确认==签名=>消息由Bob发送(?)
  • 它与Bob发送消息和使用私钥计算的签名有何不同
  • 编辑

    privatekey=(95,49)#鲍勃的私钥
    公钥=(95,25)#Bob的公钥
    message=122#Eve写了一条恶意的消息
    散列=消息**65537%2**8#Eve计算散列
    sig=hash**publickey[1]%publickey[0]#Eve使用bob的公钥计算签名
    字母=(信息,信号)#伊芙将她的信息和签名发送给爱丽丝
    Alice#hash=字母[0]**65537%2**8#Alice自己计算哈希
    Alice_confirmation=Alice_hash**publickey[1]%publickey[0]#Alice计算确认
    如果Alice_confirmation==字母[1]:
    打印(“消息由Bob发送”)
    

    它起作用了。我做错了什么?(使用私钥计算的唯一东西是签名,但它也可以使用公钥计算[除非我遵循的教程(上面的链接)是错误的])

    这个问题一点也不傻。非对称加密有点令人困惑。我总是需要刷新我对这个话题的记忆,因为我不是每天都在处理它

    非对称加密的核心是一个概念,即您有一个公钥和一个私钥。您可以使用其中一个密码将消息转换为密码,但只能使用另一个密码将密码转换回消息

    因此,如果Alice想给Bob加密一条消息,她会应用Bob的公钥,甚至Alice自己也无法解密该消息,因为她需要应用Bob的私钥,而只有Bob拥有私钥。应用公钥两次将不起作用

    它就像一把锁,有两把钥匙,一把用来锁,另一把用来解锁

    如果Alice想在邮件上签名,则相反。她使用她的私钥,这是她唯一拥有的。Bob或任何有权访问其公钥的人都可以验证Alice的身份,前提是他可以安全地验证公钥实际上是Alice的。如果Eve能让Bob相信公钥属于Alice,而实际上这是Eve的密钥,并且她用私钥在消息上签名,那么这将是一次成功的攻击

    与加密示例一样,使用公钥签名和使用相同的公钥进行检查将不起作用,必须是一个用于签名,另一个用于检查。这就是为什么它被称为不对称

    您描述的攻击失败,因为Eve试图使用Bob的公钥对消息进行签名。如果Alice再次使用Bob的公钥验证此消息,验证将失败

    代码审查

    在您给出了代码示例和源代码链接之后,我能够进一步了解它

    在开始之前:如果所有操作都正确,那么应用公钥两次不会得到与先应用私钥然后应用公钥相同的结果。这就是您建议的攻击失败的原因。让我们来了解一下为什么攻击似乎在您的代码中起作用:

    问题1:从示例中转移代码时,代码中有一个bug。这条线

    hash=message**65537%2**8不正确
    
    应该使用乘法而不是幂函数

    hash=message*65537%2**8#正确
    
    这个错误发生在你身上,但从现在开始,没有什么是你的错,因为你链接的源本身就是错误的。因此,让我们继续一点一点地修复代码

    我将切换到使用私钥签名和使用公钥检查的常规情况,以确保算法有效,然后我们将再次运行您的攻击

    问题2:
    爱丽丝确认
    计算不正确。其思想是Bob计算散列,然后加密散列以获得签名。现在,Alice解密签名并将其与散列进行比较,她也会计算散列。最后一步在示例中被切换

    那么这个

    Alice\u confirmation=Alice\u hash**publickey[1]%publickey[0]
    如果Alice_confirmation==sig:
    打印(“消息由Bob发送”)
    
    实际上应该切换为如下所示:

    Alice\u confirmation=sig**publickey[1]%publickey[0]
    如果Alice\u confirmation==Alice\u hash:
    打印(“消息由Bob发送”)
    
    这是一个关键的区别,也是你的攻击似乎有效的原因。如果我没有弄错的话,副作用是正确签名的消息将无法通过测试(但由于问题1,您的原始代码中没有出现这种情况)

    问题3:我无法重建您是如何获得私钥和公钥的,因此我将使用示例网站提供的私钥和公钥。这里的问题是,作为规则,散列必须小于n。在您的情况下,散列可以增长到255(由于
    %2**8
    ),大于n=91。这在网站上更糟糕,因为他们在散列函数中使用了
    %2**32
    ,这会产生更多的数字

    因此,让我们取而代之的是维基百科页面上提供的值。我们鼓励您尝试使用自己的哈希函数,只需确保它们对于您的哈希函数范围足够大即可

    公钥:n=3233,e=17

    私钥:n=3233,d=413

    在这里,哈希函数可以工作,因为应用
    %2**8
    可以保证结果小于256,因此小于n=3233。一般来说是这样的
    The message was sent by Bob
    
    message: 122, signature: 1830
    hash: 122, confirmation: 122
    
    The message was not sent by Bob
    
    message: 122, signature: 1159
    hash: 122, confirmation: 1891