认证加密要求我们使用某种可接受的标准来加密和认证消息。因此,我们既对消息进行了加密,又对消息进行了计算以验证其未被篡改。
此问题概述了一种执行基于密码的密钥加强和加密的方法:
/* 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中执行身份验证加密的公认标准是什么?
我建议使用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模式-请参阅注释。