SoftHSM es una implementación de software de HSM (Módulo de seguridad de hardware) que tiene como objetivo realizar todas las funciones que realizaría un HSM adecuado sin proporcionar las protecciones de seguridad de hardware que ofrece un HSM real. Si es un usuario que no está dispuesto a invertir en un nuevo dispositivo de hardware, puede usar SoftHSM, que es un almacén criptográfico accesible a través de una interfaz PKCS#11. Se desarrolla como parte del proyecto OpenDNSSEC diseñado para cumplir con los requisitos de OpenDNSSEC, pero también puede funcionar junto con otros productos criptográficos debido a su interfaz PKCS#11. Este artículo le ayudará a instalar SoftHSM.
Cómo instalar SoftHSM
Puede instalar SoftHSM de varias formas. Primero, veamos a través de administradores de paquetes como apt-get
para Ubuntu y yum
para CentOS.
SoftHSM depende de la biblioteca criptográfica a continuación y su versión requerida:
Botan 2.0.0 (Use at least 2.6.0 for better performance) or OpenSSL 1.0.0
Cómo instalar SoftHSM en Ubuntu
Use los siguientes comandos para instalar SoftHSM
# sudo apt-get install softhsmVersión antigua de SoftHSM
Si la versión de SoftHSM es antigua y necesita la última versión, siga la instalación de origen a continuación.
Cómo instalar SoftHSM en CentOS
Utilice YUM para instalar SoftHSM
$ sudo yum install softhsm
También puede descargar el paquete rpm de SoftHSM e instalarlo de la siguiente manera:
$ wget http://mirror.centos.org/centos/7/os/x86_64/Packages/softhsm-2.1.0-3.el7.x86_64.rpm
$ sudo yum install softhsm-2.1.0-3.el7.x86_64.rpm -y or $ sudo rpm -Uvh softhsm-2.1.0-3.el7.x86_64.rpm
Cómo instalar SoftHSM a través de la compilación fuente
Asegúrese de tener GNU Autotools (Autoconf, Automake, Libtool) para compilar el software. También se recomienda instalar pkg-config
para que el script de configuración pueda encontrar el software instalado. También necesita libp11-kit-dev
para instalar SoftHSM como módulo PKCS#11 en el sistema.
# git clone https://github.com/opendnssec/SoftHSMv2.git # cd SoftHSMv2
Paso 3: Configurar el script de instalación
$ ./configure
Siga si encuentra que la biblioteca OpenSSL no es compatible con GOST
$ make
$ sudo make install
Cómo usar SoftHSM
Después de instalar SoftHSM, puede acceder a él a través de los comandos de la utilidad SoftHSM como se muestra a continuación.
$ softhsm2-util
Para inicializar el token de software, ejecute el siguiente comando:
$ softhsm2-util --init-token --slot 0 --label "encryptionkey"
Al inicializar el token de software, se le pedirá que configure el pin de usuario y el pin SO. El pin de usuario lo utiliza una aplicación para interactuar con el token y el pin SO para reinicializar el token. Por lo tanto, debe recordar el pin que va a establecer.
El siguiente comando enumerará las ranuras:
$ softhsm2-util --show-slots Available slots: Slot 462451351 Slot info: Description: SoftHSM slot ID 0x1b907297 Manufacturer ID: SoftHSM project Hardware version: 2.5 Firmware version: 2.5 Token present: yes Token info: Manufacturer ID: SoftHSM project Model: SoftHSM v2 Hardware version: 2.5 Firmware version: 2.5 Serial number: 360a5ad59b907297 Initialized: yes User PIN init.: yes Label: encryptionkey Slot 1 Slot info: Description: SoftHSM slot ID 0x1 Manufacturer ID: SoftHSM project Hardware version: 2.5 Firmware version: 2.5 Token present: yes Token info: Manufacturer ID: SoftHSM project Model: SoftHSM v2 Hardware version: 2.5 Firmware version: 2.5 Serial number: Initialized: no User PIN init.: no Label:
Eso es todo, el SoftHSM se ha instalado y configurado con éxito. ¿Deberíamos ahora comunicarnos con él programáticamente?
Para comunicarnos con SoftHSM, necesitamos crear un archivo de configuración que debe almacenarse en el directorio raíz del proyecto.
name = SoftHSM library = /usr/local/lib/softhsm/libsofthsm2.so slot = 462451351 attributes(generate, *, *) = { CKA_TOKEN = true } attributes(generate, CKO_CERTIFICATE, *) = { CKA_PRIVATE = false } attributes(generate, CKO_PUBLIC_KEY, *) = { CKA_PRIVATE = false }Reemplazar ranura
Debe reemplazar la identificación de la ranura con la suya propia.
Permítame mostrarle un programa Java para comunicarse con SoftHSM. El programa tomará una cadena como entrada, la cifrará y la descifrará para nosotros.
package tg.blr; import java.io.FileWriter; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Scanner; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class SoftHsmTest { private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding"; public static String encodedString = new String(); static { Security.addProvider(new BouncyCastleProvider()); } static byte[] decryptbytes; public static void main(String[] args) { System.out.println("Enter the text to be encrypted: "); Scanner s = new Scanner(System.in); String inputtext = s.nextLine(); s.close(); try { String filePath = "/usr/local/lib/softhsm/libsofthsm2.so"; //To create softhsm.cfg FileWriter fw = new FileWriter("softhsm.cfg"); fw.write("name = SoftHSM\n" + "library = " + filePath); //Change the slot ID fw.write("\n slot = 462451351\n" + "attributes(generate, *, *) = {\n"); fw.write("\t CKA_TOKEN = true\n}\n" + "attributes(generate, CKO_CERTIFICATE, *) = {\n"); fw.write("\t CKA_PRIVATE = false\n}\n" + "attributes(generate, CKO_PUBLIC_KEY, *) = {\n"); fw.write("\t CKA_PRIVATE = false\n}\n"); fw.close(); } catch (IOException e2) { e2.printStackTrace(); } 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); //User pin created while initializing soft token char[] pin = "sukumar123".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, "sukumar123".toCharArray(), null); keyStore.store(null); SecretKey key1 = (SecretKey) keyStore.getKey("AA", "sukumar123".toCharArray()); System.out.println("the algorithm: "+key1.getAlgorithm()+", the key: "+key1.toString()+", format: "+key1.serialVersionUID); String encryptedString = performEncryption(key1, inputtext); System.out.println("encryptedString : "+encryptedString); performDecryption(key1, encryptedString); } 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 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 { } } }
Salida de muestra:
Si tiene un error:Excepción de tamaño de bloque ilegal:CKR_ENCRYPTED_DATA_LEN_RANGE, entonces aquí está la solución para arreglar lo mismo.