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.OutputStream; 021import java.security.InvalidAlgorithmParameterException; 022import java.security.InvalidKeyException; 023import java.security.Key; 024import java.security.SecureRandom; 025import javax.crypto.spec.IvParameterSpec; 026 027import org.apache.hadoop.hbase.io.crypto.Encryptor; 028import org.apache.yetus.audience.InterfaceAudience; 029import org.apache.yetus.audience.InterfaceStability; 030 031import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 032 033@InterfaceAudience.Private 034@InterfaceStability.Evolving 035public class AESEncryptor implements Encryptor { 036 037 private javax.crypto.Cipher cipher; 038 private SecureRandom rng; 039 private Key key; 040 private byte[] iv; 041 private boolean initialized = false; 042 043 public AESEncryptor(javax.crypto.Cipher cipher, SecureRandom rng) { 044 this.cipher = cipher; 045 this.rng = rng; 046 } 047 048 javax.crypto.Cipher getCipher() { 049 return cipher; 050 } 051 052 @Override 053 public void setKey(Key key) { 054 this.key = key; 055 } 056 057 @Override 058 public int getIvLength() { 059 return AES.IV_LENGTH; 060 } 061 062 @Override 063 public int getBlockSize() { 064 return AES.BLOCK_SIZE; 065 } 066 067 @Override 068 public byte[] getIv() { 069 return iv; 070 } 071 072 @Override 073 public void setIv(byte[] iv) { 074 if (iv != null) { 075 Preconditions.checkArgument(iv.length == AES.IV_LENGTH, "Invalid IV length"); 076 } 077 this.iv = iv; 078 } 079 080 @Override 081 public OutputStream createEncryptionStream(OutputStream out) { 082 if (!initialized) { 083 init(); 084 } 085 return new javax.crypto.CipherOutputStream(out, cipher); 086 } 087 088 @Override 089 public void reset() { 090 init(); 091 } 092 093 protected void init() { 094 try { 095 if (iv == null) { 096 iv = new byte[getIvLength()]; 097 rng.nextBytes(iv); 098 } 099 cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); 100 } catch (InvalidKeyException e) { 101 throw new RuntimeException(e); 102 } catch (InvalidAlgorithmParameterException e) { 103 throw new RuntimeException(e); 104 } 105 initialized = true; 106 } 107 108}