33import pl .mlodawski .security .pkcs11 .*;
44import pl .mlodawski .security .pkcs11 .model .*;
55
6+ import java .nio .file .Files ;
67import java .nio .file .Path ;
78import 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 .*;
1212
1313class PKCS11 {
1414 private final Path PKCS11_WRAPPER_PATH ;
@@ -76,15 +76,24 @@ public void onDeviceError(PKCS11Device device, Exception error) {
7676 signMessage (manager , session );
7777 break ;
7878 case 3 :
79- encryptDecryptData (manager , session );
79+ signFile (manager , session );
8080 break ;
8181 case 4 :
82- listSupportedAlgorithms (manager , session );
82+ verifyFileSignature (manager , session );
8383 break ;
8484 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 :
8594 selectedDevice = null ;
8695 return ;
87- case 6 :
96+ case 9 :
8897 session .close ();
8998 selectedDevice = null ;
9099 PIN = null ;
@@ -96,14 +105,14 @@ public void onDeviceError(PKCS11Device device, Exception error) {
96105 System .out .println ("Invalid choice. Please try again." );
97106 }
98107
99- if (choice == 6 ) {
100- break ;
101- }
108+ // if (choice == 6) {
109+ // break;
110+ // }
102111 }
103112 } catch (Exception e ) {
104113 System .out .println ("Session error: " + e .getMessage ());
105114 selectedDevice = null ;
106- PIN = null ;
115+ PIN = null ;
107116 }
108117 } catch (Exception e ) {
109118 System .out .println ("An error occurred: " + e .getMessage ());
@@ -115,6 +124,156 @@ public void onDeviceError(PKCS11Device device, Exception error) {
115124 }
116125 }
117126
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+ }
118277
119278 private boolean handleDeviceChange (PKCS11Manager manager ) {
120279 int maxRetries = 3 ;
@@ -130,7 +289,6 @@ private boolean handleDeviceChange(PKCS11Manager manager) {
130289 continue ;
131290 }
132291
133-
134292 if (!getPINFromUser ()) {
135293 retryCount ++;
136294 continue ;
@@ -223,10 +381,13 @@ private void displayMenu() {
223381 System .out .println ("Current device: " + selectedDevice .getLabel ());
224382 System .out .println ("1. List Available Certificates" );
225383 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" );
230391 System .out .print ("Enter your choice: " );
231392 }
232393
@@ -294,12 +455,20 @@ private void encryptDecryptData(PKCS11Manager manager, PKCS11Session session) {
294455 Scanner scanner = new Scanner (System .in );
295456 String dataToEncrypt = scanner .nextLine ();
296457
297- PKCS11Crypto decryptor = new PKCS11Crypto ();
458+ PKCS11Crypto crypto = new PKCS11Crypto ();
298459
299- byte [] encryptedData = decryptor .encryptData (dataToEncrypt .getBytes (), selectedPair .getCertificate ());
460+ // Encrypt data
461+ byte [][] encryptedPackage = crypto .encryptData (dataToEncrypt .getBytes (), selectedPair .getCertificate ());
300462 System .out .println ("Data encrypted successfully." );
463+ System .out .println ("Encrypted data (Base64): " + Base64 .getEncoder ().encodeToString (encryptedPackage [2 ]));
301464
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+ );
303472 System .out .println ("Decrypted data: " + new String (decryptedData ));
304473
305474 if (dataToEncrypt .equals (new String (decryptedData ))) {
@@ -309,10 +478,8 @@ private void encryptDecryptData(PKCS11Manager manager, PKCS11Session session) {
309478 }
310479 } catch (IllegalArgumentException e ) {
311480 System .out .println ("Invalid input: " + e .getMessage ());
312- throw e ;
313481 } catch (Exception e ) {
314482 System .out .println ("Error during encryption/decryption: " + e .getMessage ());
315- throw e ;
316483 }
317484 }
318485
@@ -339,6 +506,7 @@ private void listSupportedAlgorithms(PKCS11Manager manager, PKCS11Session sessio
339506 }
340507}
341508
509+
342510public class PKCS11Example {
343511 public static void main (String [] args ) {
344512 String userDir = System .getProperty ("user.dir" );
@@ -347,4 +515,4 @@ public static void main(String[] args) {
347515 );
348516 example .run ();
349517 }
350- }
518+ }
0 commit comments