AesCbcKey.java
package cn.home1.oss.lib.common.crypto;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.Integer.parseInt;
import com.google.common.base.Preconditions;
import lombok.Getter;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import cn.home1.oss.lib.common.CodecUtils;
/**
* Created by zhanghaolun on 16/11/17.
*/
public class AesCbcKey {
public static final String AES_MODE_CBC = "CBC";
@Getter
private final KeyExpression keyExpression;
@Getter
private final SecretKeySpec keySpec;
@Getter
private final IvParameterSpec cbcIv;
@Getter
private final int cbcIvLength;
public AesCbcKey(final KeyExpression keyExpression) {
this.keyExpression = keyExpression;
final String spec = keyExpression.getSpec();
final int keySize = keySize(spec);
final int cbcIvLength = cbcIvLength(spec);
final String key = keyExpression.getValue();
checkArgument(key.endsWith("="), "must ends with '='");
final byte[] keyBytes = CodecUtils.decodeBase64(key);
Preconditions.checkArgument(keyBytes.length * 8 == keySize, AesException.AesError.ILLEGAL_AES_KEY);
this.keySpec = new SecretKeySpec(keyBytes, CryptoConstants.ALGO_AES);
// first cbcIvLength bytes
this.cbcIv = new IvParameterSpec(keyBytes, 0, cbcIvLength);
//this.cbcIv = new IvParameterSpec(java.util.Arrays.copyOfRange(aesKey, 0, randomStringLength));
this.cbcIvLength = cbcIvLength;
}
public AesCbcKey(final String keyExpression) {
this(new KeyExpression(keyExpression));
}
@Override
public String toString() {
return this.keyExpression.toString();
}
public static int keySize(final String spec) {
return parseInt(spec.split(CryptoConstants.UNDERSCORE)[0].substring(3));
}
public static String keySpec(final int keySize) {
return CryptoConstants.ALGO_AES + keySize + CryptoConstants.UNDERSCORE + AES_MODE_CBC + 16;
}
public static int cbcIvLength(final String spec) {
return parseInt(spec.substring(spec.indexOf(AES_MODE_CBC) + 3));
}
}