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