1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.util;
18
19 import java.nio.charset.StandardCharsets;
20
21 import javax.crypto.Cipher;
22 import javax.crypto.spec.SecretKeySpec;
23
24
25
26
27
28
29
30
31
32
33 public class DefaultCryptor implements Cryptor {
34 private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
35
36 private static final byte[] KEY_BYTES = {0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6F, 0x6D, 0x6D, 0x6F, 0x6E, 0x73, 0x56, 0x46, 0x53};
37
38 private static final int INDEX_NOT_FOUND = -1;
39
40 private static final int BITS_IN_HALF_BYTE = 4;
41
42 private static final char MASK = 0x0f;
43
44
45
46
47 public DefaultCryptor() {
48
49 }
50
51
52 private byte[] decode(final String str) {
53 final char[] chars = str.toCharArray();
54 final int length = chars.length / 2;
55 final byte[] decoded = new byte[length];
56 if (length * 2 != chars.length) {
57 throw new IllegalArgumentException("The given string must have even number of hex chars.");
58 }
59 int index = 0;
60 for (int i = 0; i < length; i++) {
61 final int id1 = indexOf(HEX_CHARS, chars[index++]);
62 if (id1 == INDEX_NOT_FOUND) {
63 throw new IllegalArgumentException("Character " + chars[index - 1] + " at position " + (index - 1) + " is not a valid hexadecimal character");
64 }
65 final int id2 = indexOf(HEX_CHARS, chars[index++]);
66 if (id2 == INDEX_NOT_FOUND) {
67 throw new IllegalArgumentException("Character " + chars[index - 1] + " at position " + (index - 1) + " is not a valid hexadecimal character");
68 }
69 decoded[i] = (byte) (id1 << BITS_IN_HALF_BYTE | id2);
70 }
71 return decoded;
72 }
73
74
75
76
77
78
79
80
81 @Override
82 public String decrypt(final String encryptedKey) throws Exception {
83 final SecretKeySpec key = new SecretKeySpec(KEY_BYTES, "AES");
84 final Cipher cipher = Cipher.getInstance("AES");
85 cipher.init(Cipher.DECRYPT_MODE, key);
86 final byte[] decoded = decode(encryptedKey);
87 final byte[] plainText = new byte[cipher.getOutputSize(decoded.length)];
88 int ptLength = cipher.update(decoded, 0, decoded.length, plainText, 0);
89 ptLength += cipher.doFinal(plainText, ptLength);
90 return new String(plainText, StandardCharsets.UTF_8).substring(0, ptLength);
91 }
92
93
94 private String encode(final byte[] bytes) {
95 final StringBuilder builder = new StringBuilder();
96
97 for (final byte b : bytes) {
98 builder.append(HEX_CHARS[b >> BITS_IN_HALF_BYTE & MASK]);
99 builder.append(HEX_CHARS[b & MASK]);
100 }
101 return builder.toString();
102 }
103
104
105
106
107
108
109
110
111
112
113
114 @Override
115 public String encrypt(final String plainKey) throws Exception {
116 final byte[] input = plainKey.getBytes(StandardCharsets.UTF_8);
117 final SecretKeySpec key = new SecretKeySpec(KEY_BYTES, "AES");
118
119 final Cipher cipher = Cipher.getInstance("AES");
120
121
122 cipher.init(Cipher.ENCRYPT_MODE, key);
123
124 final byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
125 int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
126 ctLength += cipher.doFinal(cipherText, ctLength);
127 return encode(cipherText);
128 }
129
130 private int indexOf(final char[] array, final char valueToFind) {
131 if (array == null) {
132 return INDEX_NOT_FOUND;
133 }
134 for (int i = 0; i < array.length; i++) {
135 if (valueToFind == array[i]) {
136 return i;
137 }
138 }
139 return INDEX_NOT_FOUND;
140 }
141 }