Ho installato e configurato correttamente SoftHSM su CentOS. Per verificare se posso comunicare con SoftHSM a livello di codice, ho scritto un programma Java che interagisce con il soft token ed esegue la crittografia e la decrittografia di una stringa di input. Tuttavia, il programma è stato in grado di crittografare correttamente l'input ma non riesce a decrittografarlo. Il metodo di decrittografia non riesce con un errore – Eccezione dimensione blocco non valida – CKR_ENCRYPTED_DATA_LEN_RANGE.
Ecco il codice parziale.
String pkcs11ConfigData = "softhsm.cfg";
Provider pkcs11Provider = Security.getProvider("SunPKCS11");
pkcs11Provider = pkcs11Provider.configure(pkcs11ConfigData);
if (-1 == Security.addProvider(pkcs11Provider)) {
throw new RuntimeException("could not add security provider");
} else {
System.out.println("provider initialized !!!");
}
Security.addProvider(pkcs11Provider);
char[] pin = "abcdef123".toCharArray();
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance("PKCS11", pkcs11Provider);
keyStore.load(null, pin);
SecretKeySpec secretKeySpec = new SecretKeySpec("0123456789ABCDEF".getBytes(), 0, 16, "AES");
Key key = new SecretKeySpec(secretKeySpec.getEncoded(), 0, 16, "AES");
keyStore.setKeyEntry("AA", key, "abcdef123".toCharArray(), null);
keyStore.store(null);
SecretKey key1 = (SecretKey) keyStore.getKey("AA", "abcdef123".toCharArray());
System.out.println("the algorithm: "+key1.getAlgorithm()+", the key: "+key1.toString()+", format: "+key1.serialVersionUID);
doCrypto(Cipher.ENCRYPT_MODE, key1, inputtext);
doCrypto(Cipher.DECRYPT_MODE, key1, encryptedtext);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
private static void doCrypto(int cipherMode, Key key, String inputtext) throws Exception {
Key secretKey = key;
Cipher cipher;
try {
cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(cipherMode, secretKey);
byte[] inputBytes = inputtext.getBytes();
byte[] outputBytes;
outputBytes = cipher.doFinal(inputBytes);
if(cipherMode == Cipher.ENCRYPT_MODE) {
encryptedtext = outputBytes.toString();
System.out.println("==========================================");
System.out.println("encrypted text: "+outputBytes.toString());
System.out.println("==========================================");
}
if(cipherMode == Cipher.DECRYPT_MODE) {
System.out.println("*****************************************");
System.out.println("decrypted text: "+outputBytes.toString());
System.out.println("*****************************************");
}
} catch (NoSuchAlgorithmException e) {
System.out.println("No such algorithm exception");
e.printStackTrace();
} catch (NoSuchPaddingException e) {
System.out.println("No such padding exception");
e.printStackTrace();
} catch (InvalidKeyException e) {
System.out.println("Invalid key exception");
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
System.out.println("Illegal block size exception");
e.printStackTrace();
} catch (BadPaddingException e) {
System.out.println("Bad padding exception");
e.printStackTrace();
} finally {
}
} Errore di output:
Allora come ho fatto a farlo funzionare? Ecco la soluzione.
Come risolvere il Eccezione relativa alla dimensione del blocco illegale:errore CKR_ENCRYPTED_DATA_LEN_RANGE durante l'accesso a SoftHSM tramite codice Java?
Poiché sto crittografando la stringa con l'algoritmo AES, il ritorno previsto è un array di byte. Quindi la conversione di quei byte direttamente in una stringa come mostrato di seguito stava causando il problema.
encryptedtext = outputBytes.toString();
Nella riga di codice sopra, outputBytes è di tipo bytes [] e convertirlo direttamente in stringa era il problema.
Per risolvere questo problema, dobbiamo utilizzare Base64 invece di convertirlo direttamente in una stringa.
byte[] cipherText = cipher.doFinal(inputtext.getBytes("utf-8"));
encryptedText = java.util.Base64.getEncoder().encodeToString(cipherText);
Le righe precedenti sono leggermente riscritte per codificare il cipherText utilizzando Base64 e salva lo stesso in encryptedText .
Allo stesso modo, durante la decrittazione, dobbiamo convertire il Base64 stringa in un array di byte prima di decrittografare l'array di byte.
byte[] deciphered = cipher.doFinal(java.util.Base64.getDecoder().decode(encryptedText));
La riga di codice sopra suggerisce che dobbiamo eseguire Base64 decodificalo e passalo come argomento al metodo di decrittazione.
Questo è tutto! Ecco il codice completo per riferimento.
private static String performEncryption(Key secretKey, String inputtext) throws Exception {
String encryptedText = new String();
Cipher cipher;
try {
cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] cipherText = cipher.doFinal(inputtext.getBytes("utf-8"));
encryptedText = java.util.Base64.getEncoder().encodeToString(cipherText);
} catch (NoSuchAlgorithmException e) {
System.out.println("No such algorithm exception");
e.printStackTrace();
} catch (NoSuchPaddingException e) {
System.out.println("No such padding exception");
e.printStackTrace();
} catch (InvalidKeyException e) {
System.out.println("Invalid key exception");
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
System.out.println("Illegal block size exception");
e.printStackTrace();
} catch (BadPaddingException e) {
System.out.println("Bad padding exception");
e.printStackTrace();
} finally {
}
return encryptedText;
}
private static void performDecryption(Key key, String encryptedString) throws Exception {
Key secretKey = key;
Cipher cipher;
try {
cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] deciphered = cipher.doFinal(java.util.Base64.getDecoder().decode(encryptedString));
System.out.println("decrypted text: "+new String(deciphered));
} catch (NoSuchAlgorithmException e) {
System.out.println("No such algorithm exception");
e.printStackTrace();
} catch (NoSuchPaddingException e) {
System.out.println("No such padding exception");
e.printStackTrace();
} catch (InvalidKeyException e) {
System.out.println("Invalid key exception");
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
System.out.println("Illegal block size exception");
e.printStackTrace();
} catch (BadPaddingException e) {
System.out.println("Bad padding exception");
e.printStackTrace();
} finally {
}
} Grazie a questa risposta di Stackflow che mi ha aiutato a risolvere il problema.
Infine, lo screenshot dell'output riuscito.