一尘不染

用Java执行认证加密的正确方法是什么?

java

认证加密要求我们使用某种可接受的标准来加密和认证消息。因此,我们既对消息进行了加密,又对消息进行了计算以验证其未被篡改。

此问题概述了一种执行基于密码的密钥加强和加密的方法:

/* 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中执行身份验证加密的公认标准是什么?


阅读 169

收藏
2020-12-03

共1个答案

一尘不染

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

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

还要在这里查看我的答案,该答案主要是关于String编码的,但是我也成功尝试了GCM模式-请参阅注释。

2020-12-03