问题 在Java中执行经过身份验证的加密的正确方法是什么?


经过身份验证的加密要求我们使用一些可接受的标准来加密和验证消息。因此,我们都对消息进行加密并在消息上计算MAC以验证它是否未被篡改。

这个问题 概述了一种基于密码的密钥加强和加密的方法:

/* Derive the key, given password and salt. */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));

但据我所知,这不会计算密文上的任何MAC,因此不安全。在Java中执行经过身份验证的加密的标准是什么?


9840
2018-03-05 17:06


起源

如果你加密/解密完整的消息,你知道它没有被篡改!当您想要以“纯文本”发送消息(或数据)然后发送HMAC以验证纯文本时,是否使用HMAC? - TacticalCoder
进行经过身份验证的加密没有可接受的标准,它可能是(非对称)签名,MAC(例如AESCMAC),HMAC或经过身份验证的模式。虽然有一些不安全的(例如,默认的AES-MAC不是很安全)。请参阅下面的一个适合您的用例的好答案。 - Maarten Bodewes
埃里克的答案有什么问题吗? - Maarten Bodewes
@TacticalCoder你需要两者的原因是因为只有机密性的加密模式容易受到选择密文攻击。这个想法基本上是攻击者可以生成密文并提交它们进行解密,直到找到一个有效的密文。然后他们可以将其作为消息发送。 - Eric Conner


答案:


我建议使用GCM模式加密。它默认包含在最新的JDK(1.7)中。它使用计数器模式加密(流密码,不需要填充)并添加身份验证标记。一个很大的优点是它只需要一个密钥,而HMAC则为混合添加了另一个密钥。 Bouncy Castle也有一个实现,它与Oracle提供的兼容。

GCM模式加密也是TLS RFC中的功能,也是XML加密1.1(两者都不是最终的)。 GCM模式提供所有三种安全功能:数据发送的机密性,完整性和真实性。字符串将是“AES / GCM / NoPadding”而不是您正在部署的CBC。如上所述,请确保您拥有Oracle的最新JDK,或安装了Bouncy Castle提供程序。

还看看我的答案 这里,这主要是关于字符串编码,但我也成功地尝试了GCM模式 - 请参阅评论。


11
2018-03-05 21:49



与任何流密码一样,要小心你如何使用NONCE / IV,因为重新评估相同的价值会导致不安全感。 - Maarten Bodewes
是的,我认为这是所有考虑因素的最佳答案。我不得不使用JDK 1.6,所以我选择了一个基于密码的密钥加强解决方案来生成256位密钥。我取密钥的前128位并使用它来使用AES CBC进行加密,然后使用最后的128位对密文进行MAC加密。 - Eric Conner
@EricConner不要忘记MAC初始化向量! - MauganRa


当通过安全ftp将文件从一个服务器传输到另一个服务器时,我使用私钥/公钥对,驻留在“from”服务器上的私钥和驻留在“to”服务器上的公钥。

传输文件时使用私钥/公钥对是一种安全标准。

我相信它也是Java应用程序环境中的安全手段。

查看 生成和验证签名 和 生成公钥和私钥 有关在Java中使用私有/公钥对设置进行数字签名的更多详细信息。


3
2018-03-05 17:48



好的,这是一个全新的用例,但我有点苛刻。签名和PKI 是 一种有效的完整性控制和认证方法,但它是计算MAC的重要方法。 - Maarten Bodewes
@owlstead - 我简要地回忆一下你的原始评论,但现在看不到它,因为它看起来已被删除。无论如何都不用担心。我有几个人向我的答案投票,我理解为什么在几个案例中。我希望更多的人能够在悬停在downvote上时看到的原因 - “这个答案没有用”。在这种情况下,我真的相信我的答案可以帮助OP,这就是我发布它的原因。上帝禁止我们中的任何一个人只是为了点而扔东西。我们都应该努力最终互相帮助...... - Zack Macomber
确切地说,这就是为什么我认为它相当苛刻,我必须阻止自己有时太过消极。我不确定FTP和RSA是否是Eric正在寻找的,但它并不正确,所以答案应该留给自己的...... - Maarten Bodewes