View Javadoc
1   package cn.home1.oss.lib.common.crypto;
2   
3   import static com.google.common.base.Preconditions.checkArgument;
4   import static java.lang.Integer.parseInt;
5   
6   import com.google.common.base.Preconditions;
7   
8   import lombok.Getter;
9   
10  import javax.crypto.spec.IvParameterSpec;
11  import javax.crypto.spec.SecretKeySpec;
12  
13  import cn.home1.oss.lib.common.CodecUtils;
14  
15  /**
16   * Created by zhanghaolun on 16/11/17.
17   */
18  public class AesCbcKey {
19  
20    public static final String AES_MODE_CBC = "CBC";
21  
22    @Getter
23    private final KeyExpression keyExpression;
24    @Getter
25    private final SecretKeySpec keySpec;
26    @Getter
27    private final IvParameterSpec cbcIv;
28    @Getter
29    private final int cbcIvLength;
30  
31    public AesCbcKey(final KeyExpression keyExpression) {
32      this.keyExpression = keyExpression;
33  
34      final String spec = keyExpression.getSpec();
35      final int keySize = keySize(spec);
36      final int cbcIvLength = cbcIvLength(spec);
37  
38      final String key = keyExpression.getValue();
39      checkArgument(key.endsWith("="), "must ends with '='");
40  
41      final byte[] keyBytes = CodecUtils.decodeBase64(key);
42      Preconditions.checkArgument(keyBytes.length * 8 == keySize, AesException.AesError.ILLEGAL_AES_KEY);
43  
44      this.keySpec = new SecretKeySpec(keyBytes, CryptoConstants.ALGO_AES);
45      // first cbcIvLength bytes
46      this.cbcIv = new IvParameterSpec(keyBytes, 0, cbcIvLength);
47      //this.cbcIv = new IvParameterSpec(java.util.Arrays.copyOfRange(aesKey, 0, randomStringLength));
48      this.cbcIvLength = cbcIvLength;
49    }
50  
51    public AesCbcKey(final String keyExpression) {
52      this(new KeyExpression(keyExpression));
53    }
54  
55    @Override
56    public String toString() {
57      return this.keyExpression.toString();
58    }
59  
60    public static int keySize(final String spec) {
61      return parseInt(spec.split(CryptoConstants.UNDERSCORE)[0].substring(3));
62    }
63  
64    public static String keySpec(final int keySize) {
65      return CryptoConstants.ALGO_AES + keySize + CryptoConstants.UNDERSCORE + AES_MODE_CBC + 16;
66    }
67  
68    public static int cbcIvLength(final String spec) {
69      return parseInt(spec.substring(spec.indexOf(AES_MODE_CBC) + 3));
70    }
71  }