001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.io.crypto.aes; 019 020import java.io.IOException; 021import java.io.OutputStream; 022import java.security.Key; 023import java.security.SecureRandom; 024import java.util.Properties; 025import javax.crypto.spec.IvParameterSpec; 026 027import org.apache.commons.crypto.stream.CryptoOutputStream; 028import org.apache.hadoop.hbase.io.crypto.Encryptor; 029import org.apache.yetus.audience.InterfaceAudience; 030import org.apache.yetus.audience.InterfaceStability; 031 032import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 033 034@InterfaceAudience.Private 035@InterfaceStability.Evolving 036public class CommonsCryptoAESEncryptor implements Encryptor { 037 038 private String cipherMode; 039 private Properties properties; 040 private Key key; 041 private byte[] iv; 042 private boolean initialized = false; 043 private SecureRandom rng; 044 045 public CommonsCryptoAESEncryptor(String cipherMode, Properties properties, SecureRandom rng) { 046 this.cipherMode = cipherMode; 047 this.properties = properties; 048 this.rng = rng; 049 } 050 051 @Override 052 public void setKey(Key key) { 053 this.key = key; 054 } 055 056 @Override 057 public int getIvLength() { 058 return CommonsCryptoAES.IV_LENGTH; 059 } 060 061 @Override 062 public int getBlockSize() { 063 return CommonsCryptoAES.BLOCK_SIZE; 064 } 065 066 @Override 067 public byte[] getIv() { 068 return iv; 069 } 070 071 @Override 072 public void setIv(byte[] iv) { 073 Preconditions.checkNotNull(iv, "IV cannot be null"); 074 Preconditions.checkArgument(iv.length == CommonsCryptoAES.IV_LENGTH, "Invalid IV length"); 075 this.iv = iv; 076 } 077 078 @Override 079 public OutputStream createEncryptionStream(OutputStream out) { 080 if (!initialized) { 081 reset(); 082 } 083 try { 084 return new CryptoOutputStream(cipherMode, properties, out, key, new 085 IvParameterSpec(iv)); 086 } catch (IOException e) { 087 throw new RuntimeException(e); 088 } 089 } 090 091 @Override 092 public void reset() { 093 if (iv == null) { 094 iv = new byte[getIvLength()]; 095 rng.nextBytes(iv); 096 } 097 initialized = true; 098 } 099}