简体   繁体   English

在Java中验证hmac sha1签名

[英]Verifying hmac sha1 signature in Java

I'd like to know how I could verify the signature I created. 我想知道如何验证我创建的签名。 My code to create a signature looks similar to this one: HMAC-SHA1: How to do it properly in Java? 我创建签名的代码看起来与此类似: HMAC-SHA1:如何在Java中正确执行?

I send the message, the signature and the public key to verify the signature. 我发送消息,签名和公钥来验证签名。 Public and private key are generated using KeyPairGenerator. 使用KeyPairGenerator生成公钥和私钥。 How can I use the public key I have to verify my signature? 我如何使用公钥来验证我的签名? Or maybe can you suggest any good libraries for Java for signing and verifying signature that use HMAC SHA1? 或者你可以建议任何好的Java库用于签名和验证使用HMAC SHA1的签名吗?

First to clarify, the HMAC code does not generate a signature. 首先要澄清的是, HMAC代码不会生成签名。 It is a type of Message Authentication Code (MAC) . 它是一种消息验证码(MAC)

The latter link explains the difference between a signature and a MAC this way: 后一个链接以这种方式解释了签名和MAC之间的区别:

MACs differ from digital signatures as MAC values are both generated and verified using the same secret key. MAC与数字签名不同,因为MAC值都是使用相同的密钥生成和验证的。 This implies that the sender and receiver of a message must agree on the same key before initiating communications, as is the case with symmetric encryption. 这意味着在发起通信之前,消息的发送方和接收方必须就相同的密钥达成一致,如对称加密的情况。 For the same reason, MACs do not provide the property of non-repudiation offered by signatures specifically in the case of a network-wide shared secret key: any user who can verify a MAC is also capable of generating MACs for other messages. 出于同样的原因,在网络范围的共享密钥的情况下,MAC不提供由签名提供的不可否认性的属性:任何可以验证MAC的用户也能够为其他消息生成MAC。 In contrast, a digital signature is generated using the private key of a key pair, which is asymmetric encryption. 相反,使用密钥对的私钥生成数字签名,这是非对称加密。 Since this private key is only accessible to its holder, a digital signature proves that a document was signed by none other than that holder. 由于此私钥只能由其持有者访问,因此数字签名证明文档是由该持有者签署的。 Thus, digital signatures do offer non-repudiation. 因此,数字签名确实提供了不可否认性。 However, non-repudiation can be provided by systems that securely bind key usage information to the MAC key; 但是,可以通过将密钥使用信息安全地绑定到MAC密钥的系统来提供不可否认性。 the same key is in possession of two people, but one has a copy of the key that can be used for MAC generation while the other has a copy of the key in a hardware security module that only permits MAC verification. 相同的密钥拥有两个人,但是一个密钥的副本可用于MAC生成,而另一个密钥的副本在硬件安全模块中仅允许MAC验证。 This is commonly done in the finance industry. 这通常在金融业中完成。

So in order to verify an HMAC, you need to share the key that was used to generate it. 因此,为了验证HMAC,您需要共享用于生成它的密钥。 You would send the message, the HMAC, and the receiver would have the same key you used to generate the HMAC. 您将发送消息,HMAC和接收器将具有您用于生成HMAC的相同密钥。 They could then use the same algorithm to generate an HMAC from your message, and it should match the HMAC you sent. 然后,他们可以使用相同的算法从您的消息生成HMAC,它应该与您发送的HMAC匹配。 Public/private keys (assymetric) are not used for this. 公钥/私钥(assymetric)不用于此。 You need to generate a symmetric key (like AES) and securely share that with the people that will be generating/verifying the HMAC. 您需要生成对称密钥(如AES)并与将生成/验证HMAC的人员安全地共享该密钥。

This limits the HMAC to having integrity and authenticity properties only, and not non-repudiation . 这限制了HMAC仅具有integrityauthenticity属性,而不是non-repudiation

The quote above mentioned that hardware security modules could be used to enforce the key use, and then you could get non-repudiation as long as only one person could use the key for generating the HMAC. 上面的引用提到硬件安全模块可用于强制执行密钥使用,只要只有一个人可以使用密钥生成HMAC,就可以获得不可否认性。

Alternatively, you could use a hybrid approach. 或者,您可以使用混合方法。 Use a shared symmetric key to generate the HMAC. 使用共享对称密钥生成HMAC。 The HMAC in the end is a hash. HMAC到底是哈希。 You could then sign this hash with your private key (different than the key used in the HMAC). 然后,您可以使用您的私钥(与HMAC中使用的密钥不同)对此哈希进行签名。 A third party with the symmetric key and your public key could verify you signed the HMAC, and could generate their own HMAC with the message and the shared key to make sure it matched. 具有对称密钥和公钥的第三方可以验证您是否签署了HMAC,并且可以使用消息和共享密钥生成自己的HMAC以确保其匹配。 This would also give you non-repudiation. 这也会给你不可否认性。

If you want to go this route, use the Java Signature class. 如果要使用此路由,请使用Java Signature类。 The HMAC algorithm is SHA-1, and assuming your keypair is RSA, you could use the NONEwithRSA Signature algorithm since the input is already a SHA-1 hash. HMAC算法是SHA-1,假设您的密钥对是RSA,您可以使用NONEwithRSA签名算法,因为输入已经是SHA-1哈希。 Or you could hash it again with the SHA1withRSA algorithm. 或者您可以使用SHA1withRSA算法再次哈希。 As long as you generate the signature and verify with the same algorithm, it should be OK. 只要您生成签名并使用相同的算法进行验证,就应该没问题。

    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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM