1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.io.crypto;
18
19 import static org.junit.Assert.*;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.security.Key;
24
25 import javax.crypto.spec.SecretKeySpec;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.HBaseConfiguration;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.testclassification.SmallTests;
33 import org.apache.hadoop.hbase.util.Bytes;
34 import org.junit.Test;
35 import org.junit.experimental.categories.Category;
36
37 @Category(SmallTests.class)
38 public class TestEncryption {
39
40 private static final Log LOG = LogFactory.getLog(TestEncryption.class);
41
42 @Test
43 public void testSmallBlocks() throws Exception {
44 byte[] key = new byte[16];
45 Bytes.random(key);
46 byte[] iv = new byte[16];
47 Bytes.random(iv);
48 for (int size: new int[] { 4, 8, 16, 32, 64, 128, 256, 512 } ) {
49 checkTransformSymmetry(key, iv, getRandomBlock(size));
50 }
51 }
52
53 @Test
54 public void testLargeBlocks() throws Exception {
55 byte[] key = new byte[16];
56 Bytes.random(key);
57 byte[] iv = new byte[16];
58 Bytes.random(iv);
59 for (int size: new int[] { 256 * 1024, 512 * 1024, 1024 * 1024 } ) {
60 checkTransformSymmetry(key, iv, getRandomBlock(size));
61 }
62 }
63
64 @Test
65 public void testOddSizedBlocks() throws Exception {
66 byte[] key = new byte[16];
67 Bytes.random(key);
68 byte[] iv = new byte[16];
69 Bytes.random(iv);
70 for (int size: new int[] { 3, 7, 11, 23, 47, 79, 119, 175 } ) {
71 checkTransformSymmetry(key, iv, getRandomBlock(size));
72 }
73 }
74
75 @Test
76 public void testTypicalHFileBlocks() throws Exception {
77 byte[] key = new byte[16];
78 Bytes.random(key);
79 byte[] iv = new byte[16];
80 Bytes.random(iv);
81 for (int size: new int[] { 4 * 1024, 8 * 1024, 64 * 1024, 128 * 1024 } ) {
82 checkTransformSymmetry(key, iv, getRandomBlock(size));
83 }
84 }
85
86 private void checkTransformSymmetry(byte[] keyBytes, byte[] iv, byte[] plaintext)
87 throws Exception {
88 LOG.info("checkTransformSymmetry: AES, plaintext length = " + plaintext.length);
89
90 Configuration conf = HBaseConfiguration.create();
91 String algorithm =
92 conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
93 Cipher aes = Encryption.getCipher(conf, algorithm);
94 Key key = new SecretKeySpec(keyBytes, algorithm);
95
96 Encryptor e = aes.getEncryptor();
97 e.setKey(key);
98 e.setIv(iv);
99 e.reset();
100 ByteArrayOutputStream encOut = new ByteArrayOutputStream();
101 Encryption.encrypt(encOut, plaintext, 0, plaintext.length, e);
102 byte[] encrypted = encOut.toByteArray();
103
104 Decryptor d = aes.getDecryptor();
105 d.setKey(key);
106 d.setIv(iv);
107 d.reset();
108 ByteArrayInputStream encIn = new ByteArrayInputStream(encrypted);
109 ByteArrayOutputStream decOut = new ByteArrayOutputStream();
110 Encryption.decrypt(decOut, encIn, plaintext.length, d);
111
112 byte[] result = decOut.toByteArray();
113 assertEquals("Decrypted result has different length than plaintext",
114 result.length, plaintext.length);
115 assertTrue("Transformation was not symmetric",
116 Bytes.equals(result, plaintext));
117 }
118
119 private byte[] getRandomBlock(int size) {
120 byte[] b = new byte[size];
121 Bytes.random(b);
122 return b;
123 }
124
125 }