1 package cn.home1.oss.lib.common.crypto;
2
3 import static java.nio.charset.StandardCharsets.UTF_8;
4 import static java.util.Arrays.copyOfRange;
5 import static javax.crypto.Cipher.DECRYPT_MODE;
6
7 import lombok.Getter;
8 import lombok.SneakyThrows;
9
10 import java.nio.charset.Charset;
11 import java.security.Provider;
12
13 import javax.crypto.BadPaddingException;
14 import javax.crypto.Cipher;
15 import javax.crypto.IllegalBlockSizeException;
16
17 import cn.home1.oss.lib.common.CodecUtils;
18
19
20
21
22 public class AesDecryptor implements EncodeDecryptor {
23
24 @Getter
25 private final Charset charset;
26 private final Provider provider;
27 private final AesCbcKey key;
28
29 public AesDecryptor(final Provider provider, final KeyExpression keyExpression) {
30 this.charset = UTF_8;
31 this.provider = provider;
32 this.key = new AesCbcKey(keyExpression);
33 }
34
35 @Override
36 public String decrypt(final String encryptedAndEncoded) {
37 return new String(this.decryptBytes(encryptedAndEncoded), this.charset);
38 }
39
40 public byte[] decryptBytes(final String encryptedAndEncoded) {
41 final byte[] unencrypted;
42 try {
43
44 final byte[] decoded = CodecUtils.decodeBase64(encryptedAndEncoded);
45
46 unencrypted = this.decryptCipher().doFinal(decoded);
47 } catch (final IllegalBlockSizeException | BadPaddingException | IllegalArgumentException cause) {
48 throw new AesException(AesException.AesError.DECRYPT_AES_ERROR, cause);
49 }
50 try {
51
52 final byte[] unpad = Pkcs7Encoder.PKCS7_UTF8_BLOCK32.decode(unencrypted);
53 return copyOfRange(unpad, 16, unpad.length);
54 } catch (final IllegalArgumentException cause) {
55 throw new AesException(AesException.AesError.ILLEGAL_BUFFER, cause);
56 }
57 }
58
59 @SneakyThrows
60 Cipher decryptCipher() {
61 final Cipher cipher = Cipher.getInstance(CryptoConstants.AES_CBC_NOPADDING, this.provider);
62 cipher.init(DECRYPT_MODE, this.key.getKeySpec(), this.key.getCbcIv());
63 return cipher;
64 }
65 }