使用对称密钥(AES-128)对消息进行签名和验证

10
我想知道对称密钥是否可以用于签署消息?我们可以使用共享的密钥进行加密。同时,当对称密钥用于签署时,JAVA中可以使用哪个API来加载密钥并签署消息?
如果我使用java.security中的Signature,则它具有一个initSign API,但该API需要公私钥对中的私钥作为参数来签署消息。这里的密钥是对称密钥。
有什么提示吗?
3个回答

16

可以使用共享密钥计算消息认证码(MAC),然后将其用于向知道相同共享密钥的另一方确认消息的完整性和真实性。与使用私钥创建并使用公钥进行验证的数字签名不同,MAC不提供不可抵赖性(任何能够验证MAC的人也可以为另一条消息生成MAC)。

有不同形式的消息认证码;可能最常用的变体是HMAC


8
对称加密算法无法提供非否认属性,而非对称签名方案可以,即消息的接收者不能证明他们自己没有创建消息,因为他们必须知道该方案。
话虽如此,消息认证码(MAC)可以给您想要的东西:发送方和接收方都有一个共享密钥,发送方使用密钥计算MAC并将其附加到消息中,接收方计算相同的MAC并将其与接收到的消息进行比较。
虽然最常用的MAC类型(HMAC)基于哈希函数,但也有一些基于块密码(如AES)的MAC类型,例如CBC-MAC(这类似于CBC,但使用零初始化向量,并仅使用最后一个块作为输出)。 (正如noloader所说,CBC-MAC不是最安全的方法,请使用其他模式。)
在大多数使用加密的情况下,应使用消息认证,因为许多加密方案容易受到选择明文攻击的攻击。
在Java中,可以使用javax.crypto.Mac类计算(和检查)MAC。

1
CBC-MAC在变长消息上已经被攻破。CMAC是正确的CBC-MAC实现。 - jww
抱歉,我仍然不清楚。是什么决定了用于HMAC的密钥大小?我知道可以在CMAC上使用HMAC。但是我拥有的密钥是AES 128。那可以使用吗?例如:SecretKey key = new SecretKeySpec(key,“AES”)。 - user839917
最好是对MAC和加密使用不同(独立的)密钥,但HMAC很可能已经足够不同了,因此使用相同的密钥不会出现问题。对于HMAC,可以使用任何密钥长度(最多到散列函数块长度)(尽管我不知道你的实现是否支持),它将简单地用零填充到散列函数的块长度。较大的密钥提供更高的安全性,尽管你不会比散列函数的输出大小(=MAC大小)更好。 - Paŭlo Ebermann
@PaŭloEbermann:我想验证服务器使用CBCBlockCipherMac签名的消息,但在SYMBIAN中,我不知道要使用哪个类来生成CBC MAC KEY。 有人知道如何生成这种类型的密钥吗? - poppy
@poppy:MAC密钥只是一个任意的比特串,与底层块密码密钥长度相同(即AES-128为128比特)。使用您系统的加密随机数生成器(我不了解Symbian,所以请随时提出新问题)。 - Paŭlo Ebermann

1
如果你想使用对称密钥签署消息,你应该使用基于AES(或3-key TDEA或Cameilla)的CMAC。CMAC是构建在块密码之上的消息认证码(MAC)。如果你同时使用AES/3TDEA/Cameilla进行加密(也就是方便的时候),通常会使用CMAC。
你也可以使用HMAC。HMAC是构建在哈希之上的消息认证码(MAC)。如果程序中已经存在哈希值(也就是方便的时候),你可以使用HMAC。
当程序中同时存在块密码和哈希值时,我通常会使用HMAC,因为它更快。
最后(为了完整起见),不要使用MD5。它已经被破解了(尽管很多自由软件界的人认为它仍然有效)。SHA-1已经不被NIST、NESSIE和ECRYPT等机构批准用于新的应用。请使用SHA-2系列的哈希函数,或者使用Whirlpool。
关于Java的具体信息,请参考Java密码学扩展

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接