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

时间:2012-03-05 17:06:45

标签: java encryption

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

This question概述了一种执行基于密码的密钥加强和加密的方法:

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

2 个答案:

答案 0 :(得分:12)

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

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

另请查看我的回答here,主要是关于字符串编码,但我也成功尝试了GCM模式 - 请参阅评论。

答案 1 :(得分:3)

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

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

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

结帐Generating and Verifying SignaturesGenerate Public and Private Keys 有关在Java中使用私有/公钥对设置进行数字签名的更多详细信息。