3
3
import pl .mlodawski .security .pkcs11 .*;
4
4
import pl .mlodawski .security .pkcs11 .model .*;
5
5
6
+ import java .nio .file .Files ;
6
7
import java .nio .file .Path ;
7
8
import java .nio .file .Paths ;
8
- import java .util .List ;
9
- import java .util .Base64 ;
10
- import java .util .Map ;
11
- import java .util .Scanner ;
9
+ import java .security .MessageDigest ;
10
+ import java .security .NoSuchAlgorithmException ;
11
+ import java .util .*;
12
12
13
13
class PKCS11 {
14
14
private final Path PKCS11_WRAPPER_PATH ;
@@ -76,15 +76,24 @@ public void onDeviceError(PKCS11Device device, Exception error) {
76
76
signMessage (manager , session );
77
77
break ;
78
78
case 3 :
79
- encryptDecryptData (manager , session );
79
+ signFile (manager , session );
80
80
break ;
81
81
case 4 :
82
- listSupportedAlgorithms (manager , session );
82
+ verifyFileSignature (manager , session );
83
83
break ;
84
84
case 5 :
85
+ encryptDecryptData (manager , session );
86
+ break ;
87
+ case 6 :
88
+ encryptDecryptFile (manager , session );
89
+ break ;
90
+ case 7 :
91
+ listSupportedAlgorithms (manager , session );
92
+ break ;
93
+ case 8 :
85
94
selectedDevice = null ;
86
95
return ;
87
- case 6 :
96
+ case 9 :
88
97
session .close ();
89
98
selectedDevice = null ;
90
99
PIN = null ;
@@ -96,14 +105,14 @@ public void onDeviceError(PKCS11Device device, Exception error) {
96
105
System .out .println ("Invalid choice. Please try again." );
97
106
}
98
107
99
- if (choice == 6 ) {
100
- break ;
101
- }
108
+ // if (choice == 6) {
109
+ // break;
110
+ // }
102
111
}
103
112
} catch (Exception e ) {
104
113
System .out .println ("Session error: " + e .getMessage ());
105
114
selectedDevice = null ;
106
- PIN = null ;
115
+ PIN = null ;
107
116
}
108
117
} catch (Exception e ) {
109
118
System .out .println ("An error occurred: " + e .getMessage ());
@@ -115,6 +124,156 @@ public void onDeviceError(PKCS11Device device, Exception error) {
115
124
}
116
125
}
117
126
127
+ private void signFile (PKCS11Manager manager , PKCS11Session session ) {
128
+ try {
129
+ KeyCertificatePair selectedPair = selectCertificateKeyPair (manager , session );
130
+
131
+ System .out .print ("Enter path to file to sign: " );
132
+ Scanner scanner = new Scanner (System .in );
133
+ String filePath = scanner .nextLine ();
134
+
135
+ Path path = Paths .get (filePath );
136
+ if (!Files .exists (path )) {
137
+ System .out .println ("File does not exist: " + filePath );
138
+ return ;
139
+ }
140
+
141
+ byte [] fileContent = Files .readAllBytes (path );
142
+ PKCS11Signer signer = new PKCS11Signer ();
143
+ byte [] signature = signer .signMessage (manager .getPkcs11 (),
144
+ session .getSession (),
145
+ selectedPair .getKeyHandle (),
146
+ fileContent );
147
+
148
+ // Save signature to file
149
+ String signatureFilePath = filePath + ".sig" ;
150
+ Files .write (Paths .get (signatureFilePath ), signature );
151
+
152
+ System .out .println ("File signed successfully. Signature saved to: " + signatureFilePath );
153
+ System .out .println ("Signature (Base64): " + Base64 .getEncoder ().encodeToString (signature ));
154
+
155
+ // Verify signature immediately
156
+ boolean isSignatureValid = signer .verifySignature (fileContent , signature , selectedPair .getCertificate ());
157
+ System .out .println ("Signature verification: " + (isSignatureValid ? "Valid" : "Invalid" ));
158
+ } catch (Exception e ) {
159
+ System .out .println ("Error during file signing: " + e .getMessage ());
160
+ throw new RuntimeException (e );
161
+ }
162
+ }
163
+
164
+ private void verifyFileSignature (PKCS11Manager manager , PKCS11Session session ) {
165
+ try {
166
+ KeyCertificatePair selectedPair = selectCertificateKeyPair (manager , session );
167
+ Scanner scanner = new Scanner (System .in );
168
+
169
+ System .out .print ("Enter path to file to verify: " );
170
+ String filePath = scanner .nextLine ();
171
+
172
+ System .out .print ("Enter path to signature file: " );
173
+ String signatureFilePath = scanner .nextLine ();
174
+
175
+ if (!Files .exists (Paths .get (filePath ))) {
176
+ System .out .println ("File does not exist: " + filePath );
177
+ return ;
178
+ }
179
+ if (!Files .exists (Paths .get (signatureFilePath ))) {
180
+ System .out .println ("Signature file does not exist: " + signatureFilePath );
181
+ return ;
182
+ }
183
+
184
+ byte [] fileContent = Files .readAllBytes (Paths .get (filePath ));
185
+ byte [] signature = Files .readAllBytes (Paths .get (signatureFilePath ));
186
+
187
+ PKCS11Signer signer = new PKCS11Signer ();
188
+ boolean isSignatureValid = signer .verifySignature (fileContent , signature , selectedPair .getCertificate ());
189
+
190
+ System .out .println ("Signature verification result: " + (isSignatureValid ? "Valid" : "Invalid" ));
191
+ } catch (Exception e ) {
192
+ System .out .println ("Error during signature verification: " + e .getMessage ());
193
+ }
194
+ }
195
+
196
+ private void encryptDecryptFile (PKCS11Manager manager , PKCS11Session session ) {
197
+ try {
198
+ KeyCertificatePair selectedPair = selectCertificateKeyPair (manager , session );
199
+ Scanner scanner = new Scanner (System .in );
200
+
201
+ System .out .print ("Enter path to file to encrypt: " );
202
+ String filePath = scanner .nextLine ();
203
+
204
+ if (!Files .exists (Paths .get (filePath ))) {
205
+ System .out .println ("File does not exist: " + filePath );
206
+ return ;
207
+ }
208
+
209
+ byte [] fileContent = Files .readAllBytes (Paths .get (filePath ));
210
+
211
+ // Encrypt file using hybrid encryption
212
+ PKCS11Crypto crypto = new PKCS11Crypto ();
213
+ byte [][] encryptedPackage = crypto .encryptData (fileContent , selectedPair .getCertificate ());
214
+
215
+ // Save encrypted components
216
+ String encryptedKeyPath = filePath + ".key.enc" ;
217
+ String encryptedIVPath = filePath + ".iv" ;
218
+ String encryptedDataPath = filePath + ".data.enc" ;
219
+
220
+ Files .write (Paths .get (encryptedKeyPath ), encryptedPackage [0 ]);
221
+ Files .write (Paths .get (encryptedIVPath ), encryptedPackage [1 ]);
222
+ Files .write (Paths .get (encryptedDataPath ), encryptedPackage [2 ]);
223
+
224
+ System .out .println ("File encrypted successfully." );
225
+ System .out .println ("Encrypted key saved to: " + encryptedKeyPath );
226
+ System .out .println ("IV saved to: " + encryptedIVPath );
227
+ System .out .println ("Encrypted data saved to: " + encryptedDataPath );
228
+
229
+ System .out .println ("\n Do you want to decrypt the file? (y/n)" );
230
+ String answer = scanner .nextLine ().toLowerCase ();
231
+ if (!answer .equals ("y" )) {
232
+ return ;
233
+ }
234
+
235
+ // Decrypt file
236
+ byte [][] decryptPackage = new byte [][]{
237
+ Files .readAllBytes (Paths .get (encryptedKeyPath )),
238
+ Files .readAllBytes (Paths .get (encryptedIVPath )),
239
+ Files .readAllBytes (Paths .get (encryptedDataPath ))
240
+ };
241
+
242
+ byte [] decryptedData = crypto .decryptData (
243
+ manager .getPkcs11 (),
244
+ session .getSession (),
245
+ selectedPair .getKeyHandle (),
246
+ decryptPackage
247
+ );
248
+
249
+ // Save decrypted file
250
+ String decryptedFilePath = filePath + ".dec" ;
251
+ Files .write (Paths .get (decryptedFilePath ), decryptedData );
252
+ System .out .println ("File decrypted successfully. Saved to: " + decryptedFilePath );
253
+
254
+ // Calculate and display checksums
255
+ String originalChecksum = getFileChecksum (fileContent );
256
+ String decryptedChecksum = getFileChecksum (decryptedData );
257
+
258
+ System .out .println ("\n File integrity verification:" );
259
+ System .out .println ("Original file SHA-256: " + originalChecksum );
260
+ System .out .println ("Decrypted file SHA-256: " + decryptedChecksum );
261
+
262
+ if (Arrays .equals (fileContent , decryptedData )) {
263
+ System .out .println ("File integrity verified: Original and decrypted files match." );
264
+ } else {
265
+ System .out .println ("Warning: Decrypted file does not match original!" );
266
+ }
267
+ } catch (Exception e ) {
268
+ System .out .println ("Error during file encryption/decryption: " + e .getMessage ());
269
+ }
270
+ }
271
+
272
+ private String getFileChecksum (byte [] fileData ) throws NoSuchAlgorithmException {
273
+ MessageDigest digest = MessageDigest .getInstance ("SHA-256" );
274
+ byte [] hash = digest .digest (fileData );
275
+ return Base64 .getEncoder ().encodeToString (hash );
276
+ }
118
277
119
278
private boolean handleDeviceChange (PKCS11Manager manager ) {
120
279
int maxRetries = 3 ;
@@ -130,7 +289,6 @@ private boolean handleDeviceChange(PKCS11Manager manager) {
130
289
continue ;
131
290
}
132
291
133
-
134
292
if (!getPINFromUser ()) {
135
293
retryCount ++;
136
294
continue ;
@@ -223,10 +381,13 @@ private void displayMenu() {
223
381
System .out .println ("Current device: " + selectedDevice .getLabel ());
224
382
System .out .println ("1. List Available Certificates" );
225
383
System .out .println ("2. Sign a Message" );
226
- System .out .println ("3. Encrypt and Decrypt Data" );
227
- System .out .println ("4. List Supported Algorithms" );
228
- System .out .println ("5. Exit" );
229
- System .out .println ("6. Change Device" );
384
+ System .out .println ("3. Sign a File" );
385
+ System .out .println ("4. Verify File Signature" );
386
+ System .out .println ("5. Encrypt and Decrypt Data" );
387
+ System .out .println ("6. Encrypt and Decrypt File" );
388
+ System .out .println ("7. List Supported Algorithms" );
389
+ System .out .println ("8. Exit" );
390
+ System .out .println ("9. Change Device" );
230
391
System .out .print ("Enter your choice: " );
231
392
}
232
393
@@ -294,12 +455,20 @@ private void encryptDecryptData(PKCS11Manager manager, PKCS11Session session) {
294
455
Scanner scanner = new Scanner (System .in );
295
456
String dataToEncrypt = scanner .nextLine ();
296
457
297
- PKCS11Crypto decryptor = new PKCS11Crypto ();
458
+ PKCS11Crypto crypto = new PKCS11Crypto ();
298
459
299
- byte [] encryptedData = decryptor .encryptData (dataToEncrypt .getBytes (), selectedPair .getCertificate ());
460
+ // Encrypt data
461
+ byte [][] encryptedPackage = crypto .encryptData (dataToEncrypt .getBytes (), selectedPair .getCertificate ());
300
462
System .out .println ("Data encrypted successfully." );
463
+ System .out .println ("Encrypted data (Base64): " + Base64 .getEncoder ().encodeToString (encryptedPackage [2 ]));
301
464
302
- byte [] decryptedData = decryptor .decryptData (manager .getPkcs11 (), session .getSession (), selectedPair .getKeyHandle (), encryptedData );
465
+ // Decrypt data
466
+ byte [] decryptedData = crypto .decryptData (
467
+ manager .getPkcs11 (),
468
+ session .getSession (),
469
+ selectedPair .getKeyHandle (),
470
+ encryptedPackage
471
+ );
303
472
System .out .println ("Decrypted data: " + new String (decryptedData ));
304
473
305
474
if (dataToEncrypt .equals (new String (decryptedData ))) {
@@ -309,10 +478,8 @@ private void encryptDecryptData(PKCS11Manager manager, PKCS11Session session) {
309
478
}
310
479
} catch (IllegalArgumentException e ) {
311
480
System .out .println ("Invalid input: " + e .getMessage ());
312
- throw e ;
313
481
} catch (Exception e ) {
314
482
System .out .println ("Error during encryption/decryption: " + e .getMessage ());
315
- throw e ;
316
483
}
317
484
}
318
485
@@ -339,6 +506,7 @@ private void listSupportedAlgorithms(PKCS11Manager manager, PKCS11Session sessio
339
506
}
340
507
}
341
508
509
+
342
510
public class PKCS11Example {
343
511
public static void main (String [] args ) {
344
512
String userDir = System .getProperty ("user.dir" );
@@ -347,4 +515,4 @@ public static void main(String[] args) {
347
515
);
348
516
example .run ();
349
517
}
350
- }
518
+ }
0 commit comments