· 4 years ago · Oct 18, 2020, 03:22 PM
1/*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6package sk.ondros.fei.upb;
7
8import java.io.BufferedInputStream;
9import java.io.BufferedOutputStream;
10import java.io.File;
11import java.io.IOException;
12import java.security.SecureRandom;
13import java.util.Scanner;
14import java.util.Arrays;
15import java.io.FileInputStream;
16import java.io.FileOutputStream;
17import java.io.InputStream;
18import java.io.OutputStream;
19import java.nio.charset.StandardCharsets;
20
21import javax.crypto.Cipher;
22import javax.crypto.CipherInputStream;
23import javax.crypto.CipherOutputStream;
24import javax.crypto.KeyGenerator;
25import java.security.AlgorithmParameters;
26import javax.crypto.SecretKey;
27import javax.crypto.spec.IvParameterSpec;
28import javax.crypto.spec.SecretKeySpec;
29import javax.xml.bind.DatatypeConverter;
30import org.apache.commons.cli.CommandLine;
31import org.apache.commons.cli.CommandLineParser;
32import org.apache.commons.cli.DefaultParser;
33import org.apache.commons.cli.HelpFormatter;
34import org.apache.commons.cli.Option;
35import org.apache.commons.cli.Options;
36import org.apache.commons.cli.ParseException;
37import org.apache.commons.io.FileUtils;
38
39import java.security.AlgorithmParameters;
40import java.security.GeneralSecurityException;
41import java.security.Key;
42import java.security.Security;
43
44import javax.crypto.Cipher;
45import javax.crypto.KeyGenerator;
46import javax.crypto.Mac;
47import javax.crypto.SecretKey;
48import javax.crypto.spec.GCMParameterSpec;
49import javax.crypto.spec.IvParameterSpec;
50import javax.crypto.spec.SecretKeySpec;
51import org.bouncycastle.jce.provider.BouncyCastleProvider;
52
53import org.bouncycastle.util.encoders.Hex;
54
55/**
56 *
57 * @author ondro
58 */
59public class MyCrypto {
60
61 public static SecretKey createKey() throws Exception {
62 SecureRandom securerandom = new SecureRandom();
63 KeyGenerator keygenerator = KeyGenerator.getInstance("AES");
64 keygenerator.init(256, securerandom);
65 SecretKey key = keygenerator.generateKey();
66 return key;
67 }
68
69 public static void main(String args[]) throws Exception {
70
71 Security.addProvider(new BouncyCastleProvider());
72 long time = System.currentTimeMillis();
73
74 SecretKey Symmetrickey = null;
75 boolean isK = false;
76 String mode = null;
77 String filePath = null;
78 String keyPath = null;
79 String dirPath = null;
80
81 Options options = new Options();
82 options.addOption(Option.builder("f")
83 .longOpt("file")
84 .hasArg(true)
85 .desc("path to file ([REQUIRED] or use --file)")
86 .required(true)
87 .build());
88 options.addOption(Option.builder("m")
89 .longOpt("mode")
90 .hasArg(true)
91 .desc("mode ([REQUIRED] or use --mode) values [encrypt, decrypt]")
92 .required(true)
93 .build());
94 options.addOption(Option.builder("k")
95 .longOpt("key")
96 .hasArg(true)
97 .desc("Key path needed with decrypt mode")
98 .build());
99 options.addOption(Option.builder("d")
100 .longOpt("dir")
101 .hasArg(true)
102 .desc("dir path where key and encrypted file will be stored")
103 .build());
104
105 CommandLineParser parser = new DefaultParser();
106 CommandLine cmd = null;
107
108 try {
109 cmd = parser.parse(options, args);
110
111 if (cmd.hasOption("f")) {
112 filePath = cmd.getOptionValue("f");
113 }
114 if (cmd.hasOption("m")) {
115 mode = cmd.getOptionValue("m");
116 }
117 if (cmd.hasOption("k")) {
118 keyPath = cmd.getOptionValue("k");
119 isK = true;
120 }
121 if (cmd.hasOption("d")) {
122 dirPath = cmd.getOptionValue("d");
123 }
124
125 } catch (ParseException pe) {
126 System.out.println("Error parsing command-line arguments!");
127 System.out.println("Please, follow the instructions below:");
128 HelpFormatter formatter = new HelpFormatter();
129 formatter.printHelp("Log messages to sequence diagrams converter", options);
130 System.exit(1);
131 }
132
133 if (mode.equals("encrypt")) {
134 if (keyPath == null || keyPath.isEmpty()) {
135 Symmetrickey = createKey();
136 } else {
137 byte b[] = new byte[32];
138 try {
139 InputStream is = new FileInputStream(keyPath);
140 is.read(b);
141 } catch (IOException ioe) {
142 System.out.println("Invalid key path " + keyPath + " ending ...");
143 System.exit(1);
144 }
145 Symmetrickey = new SecretKeySpec(b, "AES");
146 }
147 if (dirPath == null || dirPath.isEmpty()) {
148 dirPath = new File(filePath).getParent() + "/output";
149 }
150 File f = new File(dirPath);
151 f.mkdirs();
152
153 Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding", "BC");
154 byte[] initializationVector = new byte[8];
155 SecureRandom secureRandom = new SecureRandom();
156 secureRandom.nextBytes(initializationVector);
157 IvParameterSpec ivParameterSpec = new IvParameterSpec(initializationVector);
158 cipher.init(Cipher.ENCRYPT_MODE, Symmetrickey, ivParameterSpec);
159 try {
160 byte[] b = new byte[2048];
161 BufferedInputStream is = new BufferedInputStream( new FileInputStream(filePath));
162 BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(new File(dirPath + "/" + new File(filePath).getName())));
163 CipherOutputStream cos = new CipherOutputStream(os, cipher);
164 int readBytes = 0;
165
166 os.write(initializationVector);
167 while ((readBytes = is.read(b)) != -1) {
168 cos.write(b, 0, readBytes);
169 }
170 //os.write(encrypt(b, Symmetrickey,true));
171 is.close();
172 cos.flush();
173 os.flush();
174 cos.close();
175 os.close();
176 if (!isK) {
177 OutputStream osK = new FileOutputStream(dirPath + "/key");
178 osK.write(Symmetrickey.getEncoded());
179 osK.flush();
180 osK.close();
181
182 }
183
184 } catch (IOException ioe) {
185 System.out.println("Error " + ioe.getMessage());
186 throw ioe;
187 }
188
189 } else if (mode.equals("decrypt")) {
190 if (!isK) {
191 System.out.println("Decrypt mode without key path. Ending ... ");
192 System.exit(1);
193 }
194 byte b[] = new byte[32];
195 try {
196 InputStream is = new FileInputStream(keyPath);
197 is.read(b);
198 } catch (IOException ioe) {
199 System.out.println("Invalid key path " + keyPath + " ending ...");
200 System.exit(1);
201 }
202 System.out.println("" + b.length);
203 Symmetrickey = new SecretKeySpec(b, 0, b.length, "AES");
204
205 System.out.println("The Symmetric Key is :" + DatatypeConverter.printHexBinary(Symmetrickey.getEncoded()));
206
207 if (dirPath == null || dirPath.isEmpty()) {
208 dirPath = new File(filePath).getParent() + "/output";
209 }
210 File f = new File(dirPath);
211 f.mkdirs();
212
213 try {
214 BufferedInputStream is = new BufferedInputStream(new FileInputStream(filePath));
215
216 byte[] iv = new byte[8];
217 is.read(iv);
218 Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding", "BC");
219 IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
220 cipher.init(Cipher.DECRYPT_MODE, Symmetrickey, ivParameterSpec);
221
222 b = new byte[2048];
223 CipherInputStream cis = new CipherInputStream(is, cipher);
224 BufferedOutputStream os = new BufferedOutputStream( new FileOutputStream(dirPath + "/" + new File(filePath).getName()));
225
226 int readBytes = 0;
227
228
229
230 while ((readBytes = cis.read(b)) != -1) {
231 os.write(b,0,readBytes);
232 }
233 cis.close();
234 is.close();
235 os.flush();
236 os.close();
237
238 } catch (IOException ioe) {
239 System.out.println("Error " + ioe.getMessage());
240 }
241
242 } else {
243 System.out.println("Unknown mode \"" + mode + "\" ending ...");
244 System.exit(1);
245 }
246 System.out.println("" + (System.currentTimeMillis()-time)/1000);
247 }
248}
249