javax.crypto.BadPaddingException:给定的最终块未正确填充。如果使用错误的密钥,可能会出现此类问题

问题描述 投票:0回答:1

我有以下 Spring Boot 服务用于加密和解密字符串:

@Service
public class EncryptionServiceImpl implements EncryptionService {
    // Strong AES key (256-bit)
    private static final String AES_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final int AES_KEY_SIZE = 256;

    // Generate a strong secret key for AES encryption
    private SecretKey secretKey;
    private SecureRandom secureRandom = new SecureRandom();

    private DataKeysRepository dataKeysRepository;

    @Autowired
    public EncryptionServiceImpl(DataKeysRepository dataKeysRepository) throws Exception {
        // Generate or load your AES SecretKey securely
        this.secretKey = generateSecretKey();
        if (this.secretKey == null) {
            throw new IllegalStateException("SecretKey generation failed!");
        }
        this.dataKeysRepository = dataKeysRepository;
    }

    /**
     * Generates a strong AES SecretKey.
     * @return SecretKey
     * @throws Exception If key generation fails.
     */
    private SecretKey generateSecretKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(AES_KEY_SIZE, secureRandom); // 256-bit AES key
        return keyGenerator.generateKey();
    }

    @Override
    public String encrypt(String plainText)
    {
        try {
            byte[] iv = new byte[16];
            secureRandom.nextBytes(iv);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            // Initialize cipher for encryption
            Cipher cipher = Cipher.getInstance(AES_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

            // Encrypt the plain text
            byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

            // Combine IV and encrypted text for storage/transmission
            byte[] ivAndEncryptedText = new byte[iv.length + encryptedTextBytes.length];
            System.arraycopy(iv, 0, ivAndEncryptedText, 0, iv.length);
            System.arraycopy(encryptedTextBytes, 0, ivAndEncryptedText, iv.length, encryptedTextBytes.length);

            DataKeys data = new DataKeys();
            data.setText(Base64.getEncoder().encodeToString(ivAndEncryptedText));
            data.setCreatedAt(OffsetDateTime.now());
            DataKeys key = dataKeysRepository.save(data);

            // Return UUID of the encrypted text
            return key.getId().toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String decrypt(String key)
    {
        Optional<DataKeys> byId = dataKeysRepository.findById(UUID.fromString(key));
        if (byId.isPresent()) {
            DataKeys dataKeys = byId.get();

            try {
                byte[] ivAndEncryptedText = Base64.getDecoder().decode(dataKeys.getText());

                // Extract the IV
                byte[] iv = new byte[16];
                System.arraycopy(ivAndEncryptedText, 0, iv, 0, iv.length);
                IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

                // Extract encrypted text
                byte[] encryptedTextBytes = new byte[ivAndEncryptedText.length - iv.length];
                System.arraycopy(ivAndEncryptedText, iv.length, encryptedTextBytes, 0, encryptedTextBytes.length);

                // Initialize cipher for decryption
                Cipher cipher = Cipher.getInstance(AES_CIPHER_ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);

                // Decrypt and return as plain text
                byte[] decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
                return new String(decryptedTextBytes, StandardCharsets.UTF_8);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

当我发送加密和解密文本的请求时,它工作正常。 但是当我重新启动微服务然后尝试解密字符串时,我收到错误:

javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
    at java.base/com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:861)
    at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:941)
    at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:734)
    at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
    at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2244)

在这个Java方法中:

doFinal(...)

你知道是什么原因导致这个问题吗?

java spring-boot encryption
1个回答
0
投票

但是当我重新启动微服务然后尝试解密字符串时,我收到错误

keyGenerator.init(AES_KEY_SIZE, secureRandom); // 256-bit AES key

每次初始化后都会生成一个新密钥。要解密密文,您需要相同的密钥来加密和解密,因此 oyu 需要将密钥保存在某处

© www.soinside.com 2019 - 2024. All rights reserved.