我想知道如何验证我创建的签名。我创建签名的代码与此类似:HMAC-SHA1: How to do it proper in Java?
我发送消息、签名和公钥来验证签名。公钥和私钥是使用 KeyPairGenerator 生成的。如何使用我必须验证我的签名的公钥?或者你能推荐任何好的 Java 库来签名和验证使用 HMAC SHA1 的签名吗?
我想知道如何验证我创建的签名。我创建签名的代码与此类似:HMAC-SHA1: How to do it proper in Java?
我发送消息、签名和公钥来验证签名。公钥和私钥是使用 KeyPairGenerator 生成的。如何使用我必须验证我的签名的公钥?或者你能推荐任何好的 Java 库来签名和验证使用 HMAC SHA1 的签名吗?
首先澄清一下,HMAC代码不会生成签名。它是一种消息验证码 (MAC)。
后一个链接以这种方式解释了签名和 MAC 之间的区别:
MAC 不同于数字签名,因为 MAC 值是使用相同的密钥生成和验证的。这意味着消息的发送者和接收者必须在开始通信之前就相同的密钥达成一致,就像对称加密的情况一样。出于同样的原因,MAC 不提供签名提供的不可否认性,特别是在网络范围共享密钥的情况下:任何可以验证 MAC 的用户也能够为其他消息生成 MAC。相反,数字签名是使用密钥对的私钥生成的,这是非对称加密。由于此私钥只能由其持有者访问,因此数字签名证明文件是由该持有者签署的。因此,数字签名确实提供了不可否认性。然而,将密钥使用信息安全地绑定到 MAC 密钥的系统可以提供不可否认性;相同的密钥由两个人拥有,但一个人拥有可用于 MAC 生成的密钥副本,而另一个人拥有仅允许 MAC 验证的硬件安全模块中的密钥副本。这在金融行业中很常见。
因此,为了验证 HMAC,您需要共享用于生成它的密钥。您将发送消息,即 HMAC,而接收方将拥有您用于生成 HMAC 的相同密钥。然后,他们可以使用相同的算法从您的消息中生成 HMAC,并且它应该与您发送的 HMAC 匹配。公钥/私钥(非对称)不用于此。您需要生成一个对称密钥(如 AES)并安全地与将生成/验证 HMAC 的人员共享。
这将 HMAC 限制为仅具有integrity
和authenticity
属性,而不具有non-repudiation
.
上面的引用提到硬件安全模块可以用于强制使用密钥,然后只要只有一个人可以使用密钥来生成 HMAC,就可以获得不可否认性。
或者,您可以使用混合方法。使用共享对称密钥生成 HMAC。最后的 HMAC 是一个哈希。然后,您可以使用您的私钥(与 HMAC 中使用的密钥不同)对该哈希进行签名。拥有对称密钥和您的公钥的第三方可以验证您签署了 HMAC,并可以使用消息和共享密钥生成他们自己的 HMAC,以确保它匹配。这也会给你不可否认性。
如果你想走这条路,请使用 Java Signature类。HMAC 算法是 SHA-1,假设您的密钥对是 RSA,您可以使用NONEwithRSA
签名算法,因为输入已经是 SHA-1 哈希。SHA1withRSA
或者您可以使用算法再次对其进行哈希处理。只要您生成签名并使用相同的算法进行验证,就可以了。
byte[] data = hmac.getBytes("UTF-8");
Signature mySig = Signature.getInstance("NONEwithRSA");
mySig.initSign(myPrivateKey);
mySig.update(data);
byte[] sigBytes = mySig.sign();
// And to verify.
Signature mySig2 = Signature.getInstance("NONEwithRSA");
mySig2.initVerify(myPublicKey);
boolean isSigValid = mySig2.verify(sigBytes);