HADOOP-10635. Add a method to CryptoCodec to generate SRNs for IV. Contributed by Yi Liu

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/fs-encryption@1598493 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yi Liu 2014-05-30 08:22:41 +00:00
parent 9c2848e076
commit f7921030cd
6 changed files with 125 additions and 0 deletions

View File

@ -17,6 +17,8 @@ fs-encryption (Unreleased)
HADOOP-10632. Minor improvements to Crypto input and output streams.
(Yi Liu)
HADOOP-10635. Add a method to CryptoCodec to generate SRNs for IV. (Yi Liu)
OPTIMIZATIONS
BUG FIXES

View File

@ -79,4 +79,11 @@ public static CryptoCodec getInstance(Configuration conf) {
* @param IV the IV for input stream position
*/
public abstract void calculateIV(byte[] initIV, long counter, byte[] IV);
/**
* Generate secure random.
* @param bytes length of the secure random
* @return byte[] the secure random
*/
public abstract byte[] generateSecureRandom(int bytes);
}

View File

@ -20,6 +20,7 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
@ -31,6 +32,8 @@
import com.google.common.base.Preconditions;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_DEFAULT;
/**
* Implement the AES-CTR crypto codec using JCE provider.
@ -39,6 +42,7 @@
public class JCEAESCTRCryptoCodec extends AESCTRCryptoCodec {
private Configuration conf;
private String provider;
private SecureRandom random;
public JCEAESCTRCryptoCodec() {
}
@ -52,6 +56,16 @@ public Configuration getConf() {
public void setConf(Configuration conf) {
this.conf = conf;
provider = conf.get(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY);
final String secureRandomAlg = conf.get(
HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY,
HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_DEFAULT);
try {
random = (provider != null) ?
SecureRandom.getInstance(secureRandomAlg, provider) :
SecureRandom.getInstance(secureRandomAlg);
} catch (GeneralSecurityException e) {
throw new IllegalArgumentException(e);
}
}
@Override
@ -64,6 +78,13 @@ public Decryptor createDecryptor() throws GeneralSecurityException {
return new JCEAESCTRCipher(Cipher.DECRYPT_MODE, provider);
}
@Override
public byte[] generateSecureRandom(int bytes) {
final byte[] data = new byte[bytes];
random.nextBytes(data);
return data;
}
private static class JCEAESCTRCipher implements Encryptor, Decryptor {
private final Cipher cipher;
private final int mode;

View File

@ -296,5 +296,11 @@ public class CommonConfigurationKeysPublic {
/** Class to override Impersonation provider */
public static final String HADOOP_SECURITY_IMPERSONATION_PROVIDER_CLASS =
"hadoop.security.impersonation.provider.class";
/** See <a href="{@docRoot}/../core-default.html">core-default.xml</a> */
public static final String HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY =
"hadoop.security.secure.random.algorithm";
/** Defalt value for HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY */
public static final String HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_DEFAULT =
"SHA1PRNG";
}

View File

@ -1384,4 +1384,12 @@
The buffer size used by CryptoInputStream and CryptoOutputStream.
</description>
</property>
<property>
<name>hadoop.security.secure.random.algorithm</name>
<value></value>
<description>
The secure random algorithm.
</description>
</property>
</configuration>

View File

@ -0,0 +1,81 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.crypto;
import org.apache.hadoop.conf.Configuration;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestCryptoCodec {
private static CryptoCodec codec;
@BeforeClass
public static void init() throws Exception {
Configuration conf = new Configuration();
codec = CryptoCodec.getInstance(conf);
}
@AfterClass
public static void shutdown() throws Exception {
}
@Test(timeout=120000)
public void testSecureRandom() throws Exception {
// len = 16
checkSecureRandom(16);
// len = 32
checkSecureRandom(32);
// len = 128
checkSecureRandom(128);
}
private void checkSecureRandom(int len) {
byte[] rand = codec.generateSecureRandom(len);
byte[] rand1 = codec.generateSecureRandom(len);
Assert.assertEquals(len, rand.length);
Assert.assertEquals(len, rand1.length);
Assert.assertFalse(bytesArrayEquals(rand, rand1));
}
private boolean bytesArrayEquals(byte[] expected, byte[] actual) {
if ((expected == null && actual != null) ||
(expected != null && actual == null)) {
return false;
}
if (expected == null && actual == null) {
return true;
}
if (expected.length != actual.length) {
return false;
}
for (int i = 0; i < expected.length; i++) {
if (expected[i] != actual[i]) {
return false;
}
}
return true;
}
}