11package pl .mlodawski .security .example ;
22
3+ import com .sun .jna .NativeLong ;
34import pl .mlodawski .security .pkcs11 .*;
45import pl .mlodawski .security .pkcs11 .model .*;
56
@@ -91,9 +92,15 @@ public void onDeviceError(PKCS11Device device, Exception error) {
9192 listSupportedAlgorithms (manager , session );
9293 break ;
9394 case 8 :
95+ generateHardwareRandom (manager , session );
96+ break ;
97+ case 9 :
98+ computeHardwareDigest (manager , session );
99+ break ;
100+ case 10 :
94101 selectedDevice = null ;
95102 return ;
96- case 9 :
103+ case 11 :
97104 session .close ();
98105 selectedDevice = null ;
99106 PIN = null ;
@@ -104,10 +111,6 @@ public void onDeviceError(PKCS11Device device, Exception error) {
104111 default :
105112 System .out .println ("Invalid choice. Please try again." );
106113 }
107-
108- // if (choice == 6) {
109- // break;
110- // }
111114 }
112115 } catch (Exception e ) {
113116 System .out .println ("Session error: " + e .getMessage ());
@@ -145,14 +148,12 @@ private void signFile(PKCS11Manager manager, PKCS11Session session) {
145148 selectedPair .getKeyHandle (),
146149 fileContent );
147150
148- // Save signature to file
149151 String signatureFilePath = filePath + ".sig" ;
150152 Files .write (Paths .get (signatureFilePath ), signature );
151153
152154 System .out .println ("File signed successfully. Signature saved to: " + signatureFilePath );
153155 System .out .println ("Signature (Base64): " + Base64 .getEncoder ().encodeToString (signature ));
154156
155- // Verify signature immediately
156157 boolean isSignatureValid = signer .verifySignature (fileContent , signature , selectedPair .getCertificate ());
157158 System .out .println ("Signature verification: " + (isSignatureValid ? "Valid" : "Invalid" ));
158159 } catch (Exception e ) {
@@ -208,11 +209,9 @@ private void encryptDecryptFile(PKCS11Manager manager, PKCS11Session session) {
208209
209210 byte [] fileContent = Files .readAllBytes (Paths .get (filePath ));
210211
211- // Encrypt file using hybrid encryption
212212 PKCS11Crypto crypto = new PKCS11Crypto ();
213213 byte [][] encryptedPackage = crypto .encryptData (fileContent , selectedPair .getCertificate ());
214214
215- // Save encrypted components
216215 String encryptedKeyPath = filePath + ".key.enc" ;
217216 String encryptedIVPath = filePath + ".iv" ;
218217 String encryptedDataPath = filePath + ".data.enc" ;
@@ -232,7 +231,6 @@ private void encryptDecryptFile(PKCS11Manager manager, PKCS11Session session) {
232231 return ;
233232 }
234233
235- // Decrypt file
236234 byte [][] decryptPackage = new byte [][]{
237235 Files .readAllBytes (Paths .get (encryptedKeyPath )),
238236 Files .readAllBytes (Paths .get (encryptedIVPath )),
@@ -246,12 +244,10 @@ private void encryptDecryptFile(PKCS11Manager manager, PKCS11Session session) {
246244 decryptPackage
247245 );
248246
249- // Save decrypted file
250247 String decryptedFilePath = filePath + ".dec" ;
251248 Files .write (Paths .get (decryptedFilePath ), decryptedData );
252249 System .out .println ("File decrypted successfully. Saved to: " + decryptedFilePath );
253250
254- // Calculate and display checksums
255251 String originalChecksum = getFileChecksum (fileContent );
256252 String decryptedChecksum = getFileChecksum (decryptedData );
257253
@@ -379,15 +375,20 @@ private boolean getPINFromUser() {
379375 private void displayMenu () {
380376 System .out .println ("\n --- PKCS#11 Operations Menu ---" );
381377 System .out .println ("Current device: " + selectedDevice .getLabel ());
378+ System .out .println ("--- Basic Operations ---" );
382379 System .out .println ("1. List Available Certificates" );
383- System .out .println ("2. Sign a Message" );
380+ System .out .println ("2. Sign a Message (RSA-PKCS) " );
384381 System .out .println ("3. Sign a File" );
385382 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" );
383+ System .out .println ("5. Encrypt and Decrypt Data (Hybrid) " );
384+ System .out .println ("6. Encrypt and Decrypt File (Hybrid) " );
388385 System .out .println ("7. List Supported Algorithms" );
389- System .out .println ("8. Exit" );
390- System .out .println ("9. Change Device" );
386+ System .out .println ("--- Advanced Operations ---" );
387+ System .out .println ("8. Generate Hardware Random Numbers" );
388+ System .out .println ("9. Compute Hardware Digest (Hash)" );
389+ System .out .println ("--- System ---" );
390+ System .out .println ("10. Exit" );
391+ System .out .println ("11. Change Device" );
391392 System .out .print ("Enter your choice: " );
392393 }
393394
@@ -457,12 +458,10 @@ private void encryptDecryptData(PKCS11Manager manager, PKCS11Session session) {
457458
458459 PKCS11Crypto crypto = new PKCS11Crypto ();
459460
460- // Encrypt data
461461 byte [][] encryptedPackage = crypto .encryptData (dataToEncrypt .getBytes (), selectedPair .getCertificate ());
462462 System .out .println ("Data encrypted successfully." );
463463 System .out .println ("Encrypted data (Base64): " + Base64 .getEncoder ().encodeToString (encryptedPackage [2 ]));
464464
465- // Decrypt data
466465 byte [] decryptedData = crypto .decryptData (
467466 manager .getPkcs11 (),
468467 session .getSession (),
@@ -504,6 +503,94 @@ private void listSupportedAlgorithms(PKCS11Manager manager, PKCS11Session sessio
504503 System .out .println ("Error listing algorithms: " + e .getMessage ());
505504 }
506505 }
506+
507+ private void generateHardwareRandom (PKCS11Manager manager , PKCS11Session session ) {
508+ try {
509+ Scanner scanner = new Scanner (System .in );
510+ System .out .print ("Enter number of random bytes to generate (1-1024): " );
511+ int numBytes = scanner .nextInt ();
512+
513+ if (numBytes < 1 || numBytes > 1024 ) {
514+ System .out .println ("Invalid number of bytes. Please enter a value between 1 and 1024." );
515+ return ;
516+ }
517+
518+ PKCS11Random random = new PKCS11Random (manager .getPkcs11 (), session .getSession ());
519+ byte [] randomBytes = random .generateRandomBytes (numBytes );
520+
521+ System .out .println ("\n Hardware-generated random bytes:" );
522+ System .out .println ("Hex: " + bytesToHex (randomBytes ));
523+ System .out .println ("Base64: " + Base64 .getEncoder ().encodeToString (randomBytes ));
524+ System .out .println ("Generated " + randomBytes .length + " random bytes from hardware token." );
525+ } catch (Exception e ) {
526+ System .out .println ("Error generating random numbers: " + e .getMessage ());
527+ }
528+ }
529+
530+ private void computeHardwareDigest (PKCS11Manager manager , PKCS11Session session ) {
531+ try {
532+ Scanner scanner = new Scanner (System .in );
533+
534+ System .out .println ("\n Select hash algorithm:" );
535+ PKCS11Digest .Algorithm [] algorithms = PKCS11Digest .Algorithm .values ();
536+ for (int i = 0 ; i < algorithms .length ; i ++) {
537+ System .out .printf ("%d. %s (%d bytes)%n" , i + 1 , algorithms [i ].name (), algorithms [i ].getDigestLength ());
538+ }
539+ System .out .print ("Enter choice: " );
540+ int algoChoice = scanner .nextInt ();
541+ scanner .nextLine (); // consume newline
542+
543+ if (algoChoice < 1 || algoChoice > algorithms .length ) {
544+ System .out .println ("Invalid algorithm choice." );
545+ return ;
546+ }
547+ PKCS11Digest .Algorithm selectedAlgorithm = algorithms [algoChoice - 1 ];
548+
549+ System .out .print ("Enter data to hash (or 'file:path' to hash a file): " );
550+ String input = scanner .nextLine ();
551+
552+ byte [] dataToHash ;
553+ if (input .startsWith ("file:" )) {
554+ String filePath = input .substring (5 );
555+ if (!Files .exists (Paths .get (filePath ))) {
556+ System .out .println ("File does not exist: " + filePath );
557+ return ;
558+ }
559+ dataToHash = Files .readAllBytes (Paths .get (filePath ));
560+ System .out .println ("Hashing file: " + filePath + " (" + dataToHash .length + " bytes)" );
561+ } else {
562+ dataToHash = input .getBytes ();
563+ }
564+
565+ PKCS11Digest digest = new PKCS11Digest (manager .getPkcs11 (), session .getSession ());
566+ byte [] hashResult = digest .digest (selectedAlgorithm , dataToHash );
567+
568+ System .out .println ("\n Hardware-computed " + selectedAlgorithm .name () + " digest:" );
569+ System .out .println ("Hex: " + bytesToHex (hashResult ));
570+ System .out .println ("Base64: " + Base64 .getEncoder ().encodeToString (hashResult ));
571+
572+ try {
573+ String javaAlgoName = selectedAlgorithm .name ().replace ("_" , "-" );
574+ if (javaAlgoName .equals ("SHA1" )) javaAlgoName = "SHA-1" ;
575+ MessageDigest md = MessageDigest .getInstance (javaAlgoName );
576+ byte [] softwareHash = md .digest (dataToHash );
577+ boolean matches = Arrays .equals (hashResult , softwareHash );
578+ System .out .println ("Matches software hash: " + (matches ? "Yes" : "No" ));
579+ } catch (NoSuchAlgorithmException e ) {
580+ System .out .println ("(Software comparison not available for this algorithm)" );
581+ }
582+ } catch (Exception e ) {
583+ System .out .println ("Error computing digest: " + e .getMessage ());
584+ }
585+ }
586+
587+ private String bytesToHex (byte [] bytes ) {
588+ StringBuilder sb = new StringBuilder ();
589+ for (byte b : bytes ) {
590+ sb .append (String .format ("%02x" , b ));
591+ }
592+ return sb .toString ();
593+ }
507594}
508595
509596
0 commit comments