GNU/Linux >> Znalost Linux >  >> Linux

Neplatná výjimka velikosti bloku – CKR_ENCRYPTED_DATA_LEN_RANGE [SoftHSM]

Úspěšně jsem nainstaloval a nakonfiguroval SoftHSM na CentOS. Abych si ověřil, zda mohu komunikovat se SoftHSM programově, napsal jsem program Java, který spolupracuje s softwarovým tokenem a provádí šifrování a dešifrování vstupního řetězce. Programu se však podařilo vstup úspěšně zašifrovat, ale nepodařilo se jej dešifrovat. Metoda dešifrování se nezdaří s chybou – Výjimka neplatná velikost bloku – CKR_ENCRYPTED_DATA_LEN_RANGE.

Zde je částečný kód.

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 {

}
}

Chyba výstupu:

Tak jak se mi to povedlo? Zde je řešení.

Jak opravit Neplatná výjimka velikosti bloku – chyba CKR_ENCRYPTED_DATA_LEN_RANGE při přístupu k SoftHSM pomocí kódu Java?

Protože šifruji řetězec pomocí algoritmu AES, očekávaná návratnost je pole bajtů. Takže převod těchto bajtů přímo na řetězec, jak je uvedeno níže, způsobil problém.

encryptedtext = outputBytes.toString();

Ve výše uvedeném řádku kódu outputBytes je typu bytes [] a převést jej přímo na řetězec byl problém.

K vyřešení tohoto problému musíme použít Base64 místo přímého převodu na řetězec.

byte[] cipherText = cipher.doFinal(inputtext.getBytes("utf-8"));
encryptedText = java.util.Base64.getEncoder().encodeToString(cipherText);

Výše uvedené řádky jsou mírně přepsány, aby zakódovaly cipherText pomocí Base64 a uložte totéž do encryptedText .

Podobně při dešifrování potřebujeme převést Base64 řetězec zpět do bajtového pole před dešifrováním bajtového pole.

byte[] deciphered = cipher.doFinal(java.util.Base64.getDecoder().decode(encryptedText));

Výše uvedený řádek kódu naznačuje, že musíme provést Base64 dekódovat a předat jej jako argument metodě dešifrování.

A je to! Zde je úplný kód pro referenci.

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 {

}
}

Díky této odpovědi od Stackflow, která mi pomohla problém vyřešit.

Konečně snímek obrazovky úspěšného výstupu.


Linux
  1. Jak seřadit výstup Du podle velikosti?

  2. Rozdíl mezi velikostí bloku a velikostí clusteru?

  3. Linux – určit velikost blokového zařízení?

  1. Problém s velikostí bloku nástroje USB Startup Disk Creator?

  2. Velikost složky s du

  3. Jak nastavíte velikost bloku bzip2 při použití tar?

  1. Neplatná výjimka velikosti bloku – CKR_ENCRYPTED_DATA_LEN_RANGE [SoftHSM]

  2. Jak zjistím velikost bloku oddílu ext3 v systému Linux?

  3. Vytvořte blokové zařízení v paměti RAM