在Corda中,两个节点如何相互证明它们都知道一条信息?



我想写一个Corda流程,其中只有当双方都能证明他们共享一条共同的信息时,他们才能继续交易。流程的大纲如下:

@InitiatingFlow
@StartableByRPC
class ChallengeResponseFlow(val otherParty: Party, val proofOfKnowledge: Int) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val otherPartySession = initiateFlow(otherParty)
otherPartySession.send(proofOfKnowledge)
val theirProofOfKnowledge = otherPartySession.receive<Int>().unwrap { theirProofOfKnowledge -> theirProofOfKnowledge }
verifySecretValue(theirProofOfKnowledge)
TODO("Challenge-response passed. Continue with flow.")
}
private fun verifyTheirProofOfKnowledge(theirProofOfKnowledge: Int) {
TODO("Write verification logic.")
}
}

两个问题:

  • 这里有什么知识证明可以证明我和我的交易对手知道同样的秘密?
  • 如何根据交易对手发送给我的知识证明检查他们是否知道相同的秘密?

重要的是,在这个质询-响应协议期间,秘密永远不会被泄露。

根据您的要求,有各种策略:

  1. 假设密钥有足够的熵(即至少 128 位(,双方都可以随机选择一个nonce,并将SHA3-256(secret, nonce)SHA2-256d(双哈希(甚至更好的HMAC连同他们的nonce一起发送给另一方。

注意答:正如你所注意到的,我省略了简单的SHA256,因为它容易受到长度扩展攻击。

注意B:发送一半的哈希,正如@Kid101已经提到的,仍然有效,但它降低了安全级别,因此随机数方法被认为更安全,更优雅。

注意C:nonce方法提供了额外的(可能是需要的(unlinkability属性,根据该属性,恶意攻击者无法判断是否在两个不同的事务/流中重复使用相同的secret。需要的总是生成一个新的随机数。

  1. 但是,在某些情况下,秘密没有足够的熵或根本不是随机的(即计数器或可预测的String,例如弱密码或用户ID(。然后,一个人(中间人(可以简单地暴力破解简单的哈希或MAC方法(即使应用了随机数(来轻松提取"弱"机密。此问题的解决方案更为复杂,需要某种加密(即,通过安全通道或使用经过密码身份验证的密钥协议协议发送散列消息(。

注意D:Corda节点无论如何都是通过TLS连接的,但是如果您需要保护静态数据(即检查点(,则应使用额外的加密层。

  1. 如果要提供针对重放攻击的安全性,则需要质询-响应协议。通过重放攻击,我们的意思是故意重复使用相同的随机数(即,以前的身份验证令牌以某种方式被破坏并在未来的身份验证尝试中重复使用(。第一种情况(具有足够熵的秘密(的一个技巧是从对手方接收一个挑战性随机数,并将此随机数用于身份验证令牌SHA3-256(secret, nonce)。因此,每个客户端都使用另一方收到的随机数。

  2. 扩展上述质询-响应解决方案,有时建议同时使用两个随机数,例如:

甲方发送SHA3-256(secret, noncefromPartyA, noncefromPartyB)

乙方发送SHA3-256(secret, noncefromPartyB, noncefromPartyA)

这是为了提供额外的保证,即聚合随机数由双方控制,如果其中只有一方是恶意的或其 PRNG 有缺陷,您仍然可以产生唯一的随机数。

注意E:我们应该确保noncefromPartyA != noncefromPartyB,因为第二个回复的人可以与第一方重用(转发(相同的身份验证令牌(再次是一种重放攻击(。

注意F:同样,我们强调上述哈希中的随机数顺序应该不同,以再次防止内部重放攻击,即使我们为每个用户使用不同的随机数!

我可以用 SHA256 对我的秘密进行哈希处理,将前 128 位发送到另一方,让另一方检查他的秘密 SHA256 哈希是否与他的前 128 位匹配。 然后他可以将他的下半部分发送给第一方,以验证它是否与他的匹配。

相关内容

最新更新