使用 Jasypt 使用 PBKDF2WithHmacSHA1 密钥进行基于密码的 AES 加密

Posted

技术标签:

【中文标题】使用 Jasypt 使用 PBKDF2WithHmacSHA1 密钥进行基于密码的 AES 加密【英文标题】:Using Jasypt for password based AES encryption with PBKDF2WithHmacSHA1 key 【发布时间】:2015-10-29 14:00:33 【问题描述】:

我正在实施我工作的加密机制,安全人员的要求如下:

    使用 PBKDF2WithHmacSHA512、秘密密码、256 位盐和最少 20000 次迭代创建一个 256 位密钥。 盐应该使用 SecureRandom.getInstance("SHA1PRNG"); 生成 使用 AES256 和派生密钥进行加密。

我正在尝试使用 Jasypt 的 StandardPBEStringEncryptor

encryptor.setPassword(PASSWORD);
encryptor.setAlgorithm("AES/CBC/PKCS5Padding");
encryptor.setKeyObtentionIterations(20000);
encryptor.setSaltGenerator(new RandomSaltGenerator());
encryptor.encrypt("something");

当我这样做时,我得到以下异常:

java.security.NoSuchAlgorithmException:AES/CBC/PKCS5Padding SecretKeyFactory 不可用

我是否错误地使用了 Jasypt?我在这里错过了什么?

谢谢

【问题讨论】:

如果安全人员建议以任何形式或形式进行密码加密,他应该被替换。整个想法根本不安全。密码必须经过哈希处理,而不是加密。 它不是用于用户密码,只是用于一些配置属性,例如数据库用户名、数据库密码等。它是仅在我们的 Intranet 内传递的数据,并且为了额外的安全性而不是作为第一道防线进行了加密。 【参考方案1】:

我最终联系了 Jasypt 的首席程序员 Daniel Fernández 并得到了他的回答:

恐怕 Jasypt 没有提供一种方法来为 SecretKeyFactory 和 Cipher 本身的实例化指定不同的算法。对不起。

我用这段 java 代码来做这个(没有 Jasypt):

public String encrypt(final String message) 
  final byte[] salt = generateSalt();
  final Key key = createKey(salt);

  final Cipher encryptingCipher = createCipher(Cipher.ENCRYPT_MODE, key, salt);
  final byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
  final byte[] encryptedBytes = doFinal(encryptingCipher, messageBytes);
  final byte[] data = ArrayUtils.addAll(salt, encryptedBytes);
  return BaseEncoding.base64().encode(data);


private byte[] generateSalt() 
  final SecureRandom secureRandom = new SecureRandom();
  final byte[] salt = new byte[SALT_LENGTH];
  secureRandom.nextBytes(salt);
  return salt;


private Key createKey(final byte[] salt) 
  final PBEKeySpec spec = new PBEKeySpec(PASSWORD,
                                       salt,
                                       ITERATIONS,
                                       KEY_LENGTH);
  final SecretKey secretKey;
  try 
    secretKey = keyFactory.generateSecret(spec);
   catch (final InvalidKeySpecException e) 
    throw new RuntimeException("Error creating SecretKey", e);
  
  final SecretKeySpec result = new SecretKeySpec(secretKey.getEncoded(), ALGORITHM);
  spec.clearPassword();
  return result;

【讨论】:

以上是关于使用 Jasypt 使用 PBKDF2WithHmacSHA1 密钥进行基于密码的 AES 加密的主要内容,如果未能解决你的问题,请参考以下文章

springboot使用jasypt加密敏感数据

springboot使用jasypt加密敏感数据

小白入门之 Jasypt 加密和解密

使用Jasypt对SpringBoot配置文件加密

Spring Boot集成Jasypt安全框架

Spring Boot 整合 Jasypt 加解密实战