· 6 years ago · Aug 15, 2019, 05:16 PM
1package hdpenc.cipher.aes;
2/*
3 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25import hdpenc.cipher.utilities.Tools;
26import org.apache.commons.codec.binary.Hex;
27import javax.crypto.*;
28import javax.crypto.spec.IvParameterSpec;
29import javax.crypto.spec.SecretKeySpec;
30import javax.xml.bind.DatatypeConverter;
31import java.io.UnsupportedEncodingException;
32import java.security.InvalidAlgorithmParameterException;
33import java.security.InvalidKeyException;
34import java.security.NoSuchAlgorithmException;
35import java.security.NoSuchProviderException;
36import java.security.spec.AlgorithmParameterSpec;
37import java.util.Random;
38
39
40/**
41 * @test
42 * @bug 8043836
43 * @summary Test AES ciphers with 4 different modes with NoPadding. Check if
44 * data before encryption and after decryption is the same.
45 */
46
47public class AESImpl {
48
49 private static final String ALGORITHM = "AES";
50
51 private static final String PROVIDER = "SunJCE";
52
53 private static final String[] MODES = {"CTR","CFB24","OFB32","GCM"};
54
55 private static final String PADDING = "NoPadding";
56
57
58 private static final int KEY_LENGTH = 128;
59
60 public static void main(String argv[]) throws Exception {
61 AESImpl test= new AESImpl();
62 String plain = "Jaja";
63 byte[] key = test.keyAdjust("inass".getBytes(),256);
64 System.out.println("key > "+test.toHexString(key));
65 byte[] iv = test.ivAdjust("marwa".getBytes());
66
67 byte[] cipher = test.encrypt("AES","CTR","NoPadding",plain.getBytes(),key,iv);
68 String str = Tools.byte2HexStr(cipher);
69 System.out.println(str);
70 byte[] recover = test.decrypt("AES","CTR","NoPadding",Tools.hexStr2Byte(str),key,iv);
71 System.out.println(new String(Hex.decodeHex(test.toHexString(recover).toCharArray()),"UTF-8"));
72
73
74 }
75
76 public byte[] encrypt(String algo, String mo, String pad, byte[] plainText,SecretKey key,IvParameterSpec iv) throws Exception {
77 Cipher ci;
78
79 AlgorithmParameterSpec aps = null;
80 try {
81 ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
82
83 if (!mo.equalsIgnoreCase("GCM")) {
84 ci.init(Cipher.ENCRYPT_MODE, key,iv);
85 } else {
86 ci.init(Cipher.ENCRYPT_MODE, key);
87 }
88
89 byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
90 int offset = ci.update(plainText, 0, plainText.length,
91 cipherText, 0);
92
93 ci.doFinal(cipherText, offset);
94
95 return cipherText;
96
97 } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException
98 | InvalidKeyException | InvalidAlgorithmParameterException
99 | ShortBufferException | IllegalBlockSizeException
100 | BadPaddingException e) {
101 System.out.println("Test failed!");
102 throw e;
103 }
104 }
105
106 public byte[] decrypt(String algo, String mo, String pad,byte[] cipherText,SecretKey key,IvParameterSpec iv) throws Exception {
107 Cipher ci = null;
108 AlgorithmParameterSpec aps = null;
109 try {
110 Random rdm = new Random();
111
112 ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
113
114
115 if (!mo.equalsIgnoreCase("GCM")) {
116 ci.init(Cipher.DECRYPT_MODE, key, iv);
117 } else {
118 ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
119 }
120
121 byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
122
123
124 int len = ci.doFinal(cipherText, 0, cipherText.length,
125 recoveredText);
126 byte[] tmp = new byte[len];
127
128 for (int j = 0; j < len; j++) {
129 tmp[j] = recoveredText[j];
130 }
131 return tmp;
132 } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException
133 | InvalidKeyException | InvalidAlgorithmParameterException
134 | ShortBufferException | IllegalBlockSizeException
135 | BadPaddingException e) {
136 System.out.println("Test failed!");
137 throw e;
138 }
139 }
140
141 public byte[] encrypt(String algo, String mo, String pad, byte[] plainText,byte[] encodedKey,byte[] encodedIV) throws Exception {
142 Cipher ci;
143
144 AlgorithmParameterSpec aps = null;
145 try {
146 ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
147
148 IvParameterSpec iv = new IvParameterSpec(encodedIV);
149 SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
150
151
152 if (!mo.equalsIgnoreCase("GCM")) {
153 ci.init(Cipher.ENCRYPT_MODE, key,iv);
154 } else {
155 ci.init(Cipher.ENCRYPT_MODE, key);
156 }
157
158
159 byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
160 int offset = ci.update(plainText, 0, plainText.length,
161 cipherText, 0);
162
163 ci.doFinal(cipherText, offset);
164
165 return cipherText;
166
167 } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException
168 | InvalidKeyException
169 | ShortBufferException | IllegalBlockSizeException
170 | BadPaddingException e) {
171 System.out.println("Test failed!");
172 throw e;
173 }
174 }
175
176 public byte[] decrypt(String algo, String mo, String pad,byte[] cipherText,byte[] encodedKey,byte[] encodedIV) throws Exception {
177 Cipher ci = null;
178 AlgorithmParameterSpec aps = null;
179 try {
180 Random rdm = new Random();
181
182 ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
183
184 IvParameterSpec iv = new IvParameterSpec(encodedIV);
185 SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
186
187 if (!mo.equalsIgnoreCase("GCM")) {
188 ci.init(Cipher.DECRYPT_MODE, key, iv);
189 } else {
190 ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
191 }
192
193 byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
194
195
196 int len = ci.doFinal(cipherText, 0, cipherText.length,
197 recoveredText);
198 byte[] tmp = new byte[len];
199
200 for (int j = 0; j < len; j++) {
201 tmp[j] = recoveredText[j];
202 }
203 return tmp;
204 } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException
205 | InvalidKeyException
206 | ShortBufferException | IllegalBlockSizeException
207 | BadPaddingException e) {
208 System.out.println("Test failed!");
209 throw e;
210 }
211 }
212
213 public byte[] keyAdjust(byte[] key,int keyLength){
214 int i=0;
215 String strKey = null;
216
217 if(key.length == keyLength/8) return key;
218
219 try {
220 strKey = new String(key, "UTF-8");
221 } catch (UnsupportedEncodingException e) {
222 e.printStackTrace();
223 }
224
225 if(key.length < keyLength/8){
226 while(strKey.length() < keyLength/8){
227 strKey += strKey.charAt(i++);
228 }
229 }else{
230 strKey = strKey.substring(0,keyLength/8);
231 }
232 return strKey.getBytes();
233 }
234
235 public byte[] ivAdjust(byte[] iv){
236 int i=0;
237 String strIV = null;
238
239 if(iv.length == 16) return iv;
240
241 try {
242 strIV = new String(iv, "UTF-8");
243 } catch (UnsupportedEncodingException e) {
244 e.printStackTrace();
245 }
246
247 if(iv.length < 16){
248 while(strIV.length() < 16){
249 strIV += strIV.charAt(i++);
250 }
251 }else{
252 strIV = strIV.substring(0,16);
253 }
254 return strIV.getBytes();
255 }
256
257 public int keySizeReview(int keySize){
258 return (keySize != 128 && keySize != 192 && keySize != 256) ? 128 : keySize;
259 }
260
261 public void dumpBytes(byte[] bytes){
262 for (byte b : bytes){
263 System.out.print(Integer.toHexString(b));
264 // System.out.println(Base64.getEncoder().encodeToString(bytes));
265 }
266 System.out.println();
267 }
268
269 public String toHexString(byte[] array) {
270 return DatatypeConverter.printHexBinary(array);
271 }
272
273 public byte[] toByteArray(String s) {
274 return DatatypeConverter.parseHexBinary(s);
275 }
276
277 public String getByteString(byte[] bytes){
278 String end = "";
279 for (byte b : bytes){
280 end+=Integer.toHexString(b);
281 }
282 return end;
283 }
284}