SoftHSMは、HSM(Hardware Security Module)のソフトウェア実装であり、実際のHSMによって提供されるハードウェアセキュリティ保護を提供せずに、適切なHSMが実行するすべての機能を実行することを目的としています。新しいハードウェアデバイスに投資する意思がないユーザーの場合は、PKCS#11インターフェイスを介してアクセスできる暗号化ストアであるSoftHSMを使用できます。 OpenDNSSECの要件を満たすように設計されたOpenDNSSECプロジェクトの一部として開発されていますが、PKCS#11インターフェイスにより、他の暗号化製品と連携することもできます。この記事は、SoftHSMのインストールに役立ちます。
SoftHSMのインストール方法
SoftHSMは、複数の方法でインストールできます。まず、apt-get
などのパッケージマネージャーを見てみましょう。 Ubuntuおよびyum
の場合 CentOSの場合。
SoftHSMは、以下の暗号化ライブラリとその必要なバージョンに依存します:
Botan 2.0.0 (Use at least 2.6.0 for better performance) or OpenSSL 1.0.0
UbuntuにSoftHSMをインストールする方法
以下のコマンドを使用してSoftHSMをインストールします
# sudo apt-get install softhsm古いSoftHSMバージョン
SoftHSMのバージョンが古く、最新バージョンが必要な場合は、以下のソースインストールに従ってください。
CentOSにSoftHSMをインストールする方法
YUMを使用してSoftHSMをインストールします
$ sudo yum install softhsm
SoftHSM rpmパッケージをダウンロードして、以下のようにインストールすることもできます。
$ 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
ソースコンパイルを介してSoftHSMをインストールする方法
ソフトウェアをビルドするためのGNUAutotools(Autoconf、Automake、Libtool)があることを確認してください。 pkg-config
をインストールすることもお勧めします configureスクリプトがインストールされたソフトウェアを見つけることができるようにします。 libp11-kit-dev
も必要です SoftHSMをPKCS#11モジュールとしてシステムにインストールします。
ステップ1: automake、autoconf、libtool、pkg-configgitパッケージがインストールされていることを確認してください
ステップ2: SoftHSMパッケージをダウンロードする
# git clone https://github.com/opendnssec/SoftHSMv2.git # cd SoftHSMv2
ステップ3: インストールスクリプトを構成する
$ ./configure
OpenSSLライブラリがGOSTをサポートしていない場合はフォローしてください
ステップ4: コンパイル
$ make
ステップ5: SoftHSMをインストールする
$ sudo make install
SoftHSMの使用方法
SoftHSMをインストールした後、以下に示すようにSoftHSMユーティリティコマンドを使用してアクセスできます。
$ softhsm2-util
ソフトトークンを初期化するには、次のコマンドを実行します。
$ softhsm2-util --init-token --slot 0 --label "encryptionkey"
ソフトトークンを初期化するときに、ユーザーピンとSOピンを設定するように求められます。 ユーザーピン トークンおよびSOピンと対話するためにアプリケーションによって使用されます トークンを再初期化するため。したがって、設定するピンを覚えておく必要があります。
以下のコマンドはスロットを一覧表示します:
$ 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:
これで、SoftHSMが正常にインストールおよび構成されました。プログラムで通信しますか?
SoftHSMと通信するには、プロジェクトのルートディレクトリに保存する必要のある構成ファイルを作成する必要があります。
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 }スロットを交換してください
スロットIDを自分のものに置き換える必要があります。
SoftHSMと通信するためのJavaプログラムについて説明します。プログラムは文字列を入力として受け取り、暗号化して復号化します。
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 { } } }>
出力例:
エラーが発生した場合:不正なブロックサイズの例外– CKR_ENCRYPTED_DATA_LEN_RANGE、 次に、同じ問題を修正するための解決策を示します。