错误的填充异常JPA AttributeConverter /多线程问题

时间:2019-02-14 22:19:15

标签: java multithreading jpa aes eclipselink

我有敏感数据,保存到数据库时需要加密,这样即使他们查看数据库,也没人能读取它。因此,我遵循的方法是使用AttributeConverter

我创建了这样的课程

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class SensitiveDataConverter implements AttributeConverter<String, String> {

    private final EncryptDecryptUtils encryptDecryptUtils;

    /**
     * Instantiates a new vulnerable data converter.
     * Not using {@link javax.inject.Inject}  because @Inject doesn't
     * work with AttributeConverter
     *
     */
    public SensitiveDataConverter() {
        this.encryptDecryptUtils = EncryptDecryptUtils.getInstance();
    }

    @Override
    public String convertToDatabaseColumn(String attribute) {
        return attribute != null ?  encryptDecryptUtils.encrypt(attribute): null;
    }

    @Override
    public String convertToEntityAttribute(String dbData) {
        return dbData != null ?  encryptDecryptUtils.decrypt(dbData): null;
    }

在我的Entity类中,我将敏感字段标记为

@Column
@Convert(converter = SensitiveDataConverter.class)
private String sensitiveData;

有不止一列包含此类敏感数据。

我的加密/解密代码如下所示。我正在使用128长键。

private static final byte[] IV = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
private static final IvParameterSpec IV_PARAMETER_SPEC = new IvParameterSpec(IV);
private static final int KEY_LENGTH = 128;

private final SecretKeySpec secretKeySpec;
private final Cipher cipher;

private static volatile EncryptDecryptUtils instance;

private String secretKey = "someSecretkey";

private String salt = "someSalt";

private EncryptDecryptUtils() {

    try {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(StandardCharsets.UTF_8),
                65536, KEY_LENGTH);
        SecretKey tmp = factory.generateSecret(spec);
        secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException e) {
        LOG.error("Error while encrypting: {}", e);
        throw new EncryptDecryptException("Error while initializing encryption mechanism", e);
    }

}

public static EncryptDecryptUtils getInstance() {
    if (instance == null) {
        synchronized (EncryptDecryptUtils .class) {
            if (instance == null) {
                instance = new EncryptDecryptUtils();
            }
        }
    }
    return instance;
}

public String encrypt(String stringToEncrypt){
    try {
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, IV_PARAMETER_SPEC);
        return Base64.getEncoder().encodeToString(cipher.doFinal(stringToEncrypt.getBytes(StandardCharsets.UTF_8)));
    } catch (BadPaddingException | InvalidKeyException | IllegalBlockSizeException
            | InvalidAlgorithmParameterException e) {
        LOG.error("Error while encrypting: {}", stringToEncrypt, e);
        throw new EncryptDecryptException("Error while encrypting sensitive data", e);
    }
}

public  String decrypt(String stringToDecrypt){
    try {
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, IV_PARAMETER_SPEC);
        return new String(cipher.doFinal(Base64.getDecoder().decode(stringToDecrypt)), StandardCharsets.UTF_8);
    } catch (BadPaddingException | InvalidKeyException | IllegalBlockSizeException
            | InvalidAlgorithmParameterException e) {
        LOG.error("Error while decrypting: {}", stringToDecrypt, e);
        throw new EncryptDecryptException("Error while decrypting sensitive data", e);
    }
}

整个代码流运行正常。但是不时地在解密时我会看到抛出该异常

Caused by: javax.crypto.BadPaddingException: Invalid PKCS#5 padding length: <somenumber>
    at iaik.security.cipher.f.b(Unknown Source)
    at iaik.security.cipher.a.a(Unknown Source)
    at iaik.security.cipher.a.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(Cipher.java:2164)
    at com.bmw.scmaer.scenario.util.EncryptDecryptUtils.decrypt(EncryptDecryptUtils.java:xxx)

如果我再次重新运行相同的流程。有用。它是间歇性发生的。因此,我无法找出根本原因。

我正在将JPA和eclipselink用作ORM。

非常感谢您的帮助。

0 个答案:

没有答案