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