Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Menggunakan Client SDK 3 untuk berintegrasi dengan Java Keytool dan Jarsigner
Penyimpanan kunci AWS CloudHSM adalah penyimpanan kunci JCE tujuan khusus yang menggunakan sertifikat yang terkait dengan kunci pada HSM Anda melalui alat pihak ketiga seperti keytool
dan jarsigner
. AWS CloudHSM tidak menyimpan sertifikat di HSM, karena sertifikat merupakan data publik, non-rahasia. Penyimpanan kunci AWS CloudHSM menyimpan sertifikat dalam file lokal dan memetakan sertifikat ke kunci yang sesuai pada HSM Anda.
Saat Anda menggunakan penyimpanan kunci AWS CloudHSM untuk menghasilkan kunci baru, tidak ada entri yang dihasilkan dalam file penyimpanan kunci lokal - kunci dibuat pada HSM. Demikian pula, ketika Anda menggunakan penyimpanan kunci AWS CloudHSM untuk mencari kunci, pencarian diteruskan ke HSM. Ketika Anda menyimpan sertifikat di penyimpanan kunci AWS CloudHSM, penyedia memverifikasi bahwa pasangan kunci dengan alias yang sesuai ada di HSM, dan kemudian mengaitkan sertifikat yang disediakan dengan pasangan kunci yang sesuai.
Topik
Prasyarat
Untuk menggunakan penyimpanan kunci AWS CloudHSM, Anda harus terlebih dahulu menginisialisasi dan mengatur konfigurasi AWS CloudHSM SDK JCE.
Langkah 1: Instal JCE
Untuk menginstal JCE, termasuk prasyarat klien AWS CloudHSM, ikuti langkah-langkah untuk menginstal pustaka Java.
Langkah 2: Tambahkan kredensial login HSM ke variabel lingkungan
Atur variabel lingkungan berisi kredensial login HSM Anda.
export HSM_PARTITION=PARTITION_1
export HSM_USER=<HSM user name>
export HSM_PASSWORD=<HSM password>
catatan
CloudHSM JCE menawarkan berbagai pilihan login. Untuk menggunakan penyimpanan kunci AWS CloudHSM dengan aplikasi pihak ketiga, Anda harus menggunakan login implisit dengan variabel lingkungan. Jika Anda ingin menggunakan login eksplisit melalui kode aplikasi, Anda harus membangun aplikasi Anda sendiri menggunakan penyimpanan kunci AWS CloudHSM. Untuk informasi tambahan, lihat artikel tentang Menggunakan penyimpanan kunci AWS CloudHSM.
Langkah 3: Mendaftarkan penyedia JCE
Untuk mendaftarkan penyedia JCE, dalam CloudProvider konfigurasi Java.
-
Buka file konfigurasi java.security di instalasi Java Anda, untuk mengedit.
-
Dalam file konfigurasi java.security, tambahkan
com.cavium.provider.CaviumProvider
sebagai penyedia terakhir. Misalnya, jika ada sembilan penyedia dalam file.security, tambahkan penyedia berikut sebagai penyedia terakhir di bagian tersebut. Menambahkan penyedia Cavium sebagai prioritas yang lebih tinggi dapat berdampak negatif terhadap performa sistem Anda.security.provider.10=com.cavium.provider.CaviumProvider
catatan
Power user mungkin terbiasa untuk menentukan opsi baris perintah
-providerName
,-providerclass
, dan-providerpath
saat menggunakan keytool, alih-alih memperbarui file konfigurasi keamanan. Jika Anda mencoba untuk menentukan opsi baris perintah ketika membuat kunci dengan penyimpanan kunci AWS CloudHSM, itu akan menyebabkan kesalahan.
Menggunakan tokoAWS CloudHSM kunci dengan keytool
Keytool
Saat menggunakan keytool dengan penyimpanan kunci AWS CloudHSM, tentukan argumen berikut untuk setiap perintah keytool:
-storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib
Jika Anda ingin membuat file penyimpanan kunci baru menggunakan penyimpanan kunci AWS CloudHSM, lihat MenggunakanAWS CloudHSMKeystore. Untuk menggunakan penyimpanan kunci yang ada, tentukan namanya (termasuk jalur) menggunakan argumen penyimpanan kunci pada keytool. Jika Anda menentukan file penyimpanan kunci yang tidak ada dalam perintah keytool, penyimpanan kunci AWS CloudHSM menciptakan file penyimpanan kunci baru.
Buat kunci baru dengan keytool
Anda dapat menggunakan keytool untuk menghasilkan semua jenis kunci yang didukung oleh AWS CloudHSM JCE SDK. Lihat daftar lengkap kunci dan panjang di artikel Kunci yang Didukung di Pustaka Java.
penting
Kunci yang dihasilkan melalui keytool dihasilkan dalam perangkat lunak, dan kemudian diimpor ke AWS CloudHSM sebagai kunci yang dapat diekstrak dan persisten.
Petunjuk untuk membuat kunci yang tidak dapat diekstrak secara langsung pada HSM, dan kemudian menggunakannya dengan keytool atau Jarsigner, ditampilkan dalam sampel kode di Mendaftarkan Kunci yang Sudah Ada dengan Penyimpanan Kunci AWS CloudHSM. Kami sangat menyarankan untuk membuat bukti kunci non-ekspor di luar keytool, dan kemudian mengimpor sertifikat yang sesuai ke penyimpanan kunci. Jika Anda menggunakan kunci RSA atau EC ekstrak melalui keytool dan jarsigner, penyedia mengekspor kunci dari AWS CloudHSM dan kemudian menggunakan kunci lokal untuk menandatangani operasi.
Jika Anda memiliki beberapa instans klien yang tersambung ke klaster CloudHSM Anda, perhatikan bahwa mengimpor sertifikat di penyimpanan kunci satu instans klien tidak akan secara otomatis membuat sertifikat tersebut tersedia pada instans klien lainnya. Untuk mendaftarkan kunci dan sertifikat terkait pada setiap instans klien, Anda perlu menjalankan aplikasi Java seperti yang dijelaskan dalam Hasilkan CSR menggunakan Keytool. Atau, Anda dapat membuat perubahan yang diperlukan pada satu klien dan menyalin file penyimpanan kunci yang dihasilkan untuk setiap instans klien lainnya.
Contoh 1: Untuk menghasilkan kunci AES-256 simetris dan menyimpannya dalam file penyimpanan kunci bernama, “my_keystore.store”, di direktori kerja. Ganti <secret label>dengan label unik.
keytool -genseckey -alias
<secret label>
-keyalg aes \ -keysize 256 -keystore my_keystore.store \ -storetype CloudHSM -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Contoh 2: Untuk menghasilkan key pair RSA 2048 dan menyimpannya dalam file penyimpanan kunci bernama, “my_keystore.store” di direktori kerja. Ganti <RSA key pair label>dengan label unik.
keytool -genkeypair -alias
<RSA key pair label>
\ -keyalg rsa -keysize 2048 \ -sigalg sha512withrsa \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Contoh 3: Untuk menghasilkan kunci p256 ED dan menyimpannya dalam file penyimpanan kunci bernama, “my_keystore.store” di direktori kerja. Ganti <ec key pair label>dengan label unik.
keytool -genkeypair -alias
<ec key pair label>
\ -keyalg ec -keysize 256 \ -sigalg SHA512withECDSA \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Anda dapat menemukan daftar algoritme tanda tangan yang didukung di pustaka Java.
Menghapus kunci menggunakan keytool
Penyimpanan kunci AWS CloudHSM tidak mendukung penghapusan kunci. Untuk menghapus kunci, Anda harus menggunakan fungsi deleteKey
dari alat baris perintah AWS CloudHSM,deleteKey.
Buat CSR menggunakan keytool
Anda menerima fleksibilitas terbesar dalam membuat permintaan penandatanganan sertifikat (CSR) jika menggunakan OpenSSL Dynamic Engine. Perintah berikut menggunakan keytool untuk menghasilkan CSR untuk pasangan kunci dengan alias, my-key-pair
.
keytool -certreq -alias
<key pair label>
\ -file my_csr.csr \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
catatan
Untuk menggunakan pasangan kunci dari keytool, pasangan kunci itu harus memiliki entri dalam file penyimpanan kunci tertentu. Jika Anda ingin menggunakan pasangan kunci yang dihasilkan di luar keytool, Anda harus mengimpor kunci dan metadata sertifikat ke penyimpanan kunci. Untuk petunjuk mengimpor data keystore lihat Mengimpor sertifikat Perantara dan root ke Penyimpanan Kunci AWS CloudHSM menggunakan Keytool.
Menggunakan keytool untuk mengimpor sertifikat perantara dan root ke penyimpananAWS CloudHSM kunci
Untuk mengimpor sertifikat CA, Anda harus mengaktifkan verifikasi rantai sertifikat penuh pada sertifikat yang baru diimpor. Perintah berikut menunjukkan sebuah contoh.
keytool -import -trustcacerts -alias rootCAcert \ -file rootCAcert.cert -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Jika Anda menghubungkan beberapa instans klien ke klaster AWS CloudHSM, mengimpor sertifikat pada satu penyimpanan kunci instans klien tidak akan secara otomatis membuat sertifikat tersebut tersedia pada instans klien lainnya. Anda harus mengimpor sertifikat pada setiap instans klien.
Menggunakan keytool untuk menghapus sertifikat dari tokoAWS CloudHSM kunci
Perintah berikut menunjukkan contoh bagaimana untuk menghapus sertifikat dari penyimpanan kunci keytool Java.
keytool -delete -alias mydomain -keystore \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Jika Anda menghubungkan beberapa instans klien ke klaster AWS CloudHSM, menghapus sertifikat di satu penyimpanan kunci satu instans klien tidak akan secara otomatis menghapus sertifikat tersebut dari instans klien lainnya. Anda harus menghapus sertifikat pada setiap instans klien.
Mengimpor sertifikat kerja ke tokoAWS CloudHSM kunci menggunakan keytool
Setelah permintaan penandatanganan sertifikat (CSR) ditandatangani, Anda dapat mengimpornya ke penyimpanan kunci AWS CloudHSM dan mengaitkannya dengan pasangan kunci yang sesuai. Perintah berikut memberikan sebuah contoh.
keytool -importcert -noprompt -alias
<key pair label>
\ -file my_certificate.crt \ -keystore my_keystore.store -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Alias harus menjadi pasangan kunci dengan sertifikat terkait di penyimpanan kunci. Jika kunci yang dihasilkan di luar keytool, atau dihasilkan pada instans klien yang berbeda, Anda harus terlebih dahulu mengimpor kunci dan metadata sertifikat ke penyimpanan kunci. Untuk petunjuk tentang mengimpor metadata sertifikat, lihat contoh kode di Mendaftarkan Kunci yang Sudah Ada dengan Penyimpanan Kunci AWS CloudHSM.
Rantai sertifikat harus dapat diverifikasi. Jika Anda tidak dapat memverifikasi sertifikat, Anda mungkin perlu mengimpor sertifikat tanda tangan (otoritas sertifikat) ke penyimpanan kunci sehingga rantai dapat diverifikasi.
Mengekspor sertifikat menggunakan keytool
Contoh berikut menghasilkan sertifikat dalam format X.509 biner. Untuk mengekspor sertifikat yang dapat dibaca manusia, tambahkan -rfc
ke perintah -exportcert
.
keytool -exportcert -alias
<key pair label>
\ -file my_exported_certificate.crt \ -keystore my_keystore.store \ -storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib/
Menggunakan tokoAWS CloudHSM kunci dengan jarsigner
Jarsigner adalah utilitas baris perintah populer untuk menandatangani file JAR menggunakan kunci yang disimpan dengan aman pada HSM. Tutorial lengkap tentang Jarsigner ada di luar lingkup dokumentasi AWS CloudHSM. Bagian ini menjelaskan parameter Jarsigner yang harus Anda gunakan untuk menandatangani dan memverifikasi tanda tangan dengan AWS CloudHSM sebagai root kepercayaan melalui penyimpanan kunci AWS CloudHSM.
Menyiapkan kunci dan sertifikat
Sebelum Anda dapat menandatangani file JAR dengan Jarsigner, pastikan Anda telah mengatur atau menyelesaikan langkah-langkah berikut:
-
Ikuti petunjuk diPrasyarat penyimpanan kunci AWS CloudHSM.
-
Atur kunci penandatanganan Anda dan sertifikat terkait dan rantai sertifikat yang harus disimpan dalam penyimpanan kunci AWS CloudHSM dari server atau instans klien saat ini. Buat kunci pada AWS CloudHSM lalu impor metadata terkait ke penyimpanan kunci AWS CloudHSM. Gunakan contoh kode di Mendaftarkan Kunci yang Sudah Ada dengan Penyimpanan Kunci AWS CloudHSM untuk mengimpor metadata ke penyimpanan kunci. Jika Anda ingin menggunakan keytool untuk mengatur kunci dan sertifikat, lihat Buat kunci baru dengan keytool. Jika Anda menggunakan beberapa instans klien untuk menandatangani JAR Anda, buat kunci dan impor rantai sertifikat. Kemudian, salin file penyimpanan kunci yang dihasilkan ke setiap instans klien. Jika Anda sering membuat kunci baru, Anda mungkin merasa lebih mudah untuk secara individual mengimpor sertifikat ke setiap instans klien.
-
Seluruh rantai sertifikat harus dapat diverifikasi. Agar rantai sertifikat dapat diverifikasi, Anda mungkin perlu menambahkan sertifikat CA dan sertifikat perantara untuk penyimpanan kunci AWS CloudHSM. Lihat cuplikan kode di Menandatangani file JAR menggunakan AWS CloudHSM dan Jarsigner untuk instruksi menggunakan kode Java untuk memverifikasi rantai sertifikat. Jika mau, Anda dapat menggunakan keytool untuk mengimpor sertifikat. Untuk petunjuk tentang cara menggunakan keytool, lihat Menggunakan Keytool untuk mengimpor sertifikat perantara dan root ke penyimpanan kunci AWS CloudHSM.
Tandatangani file JAR menggunakanAWS CloudHSM dan jarsigner
Gunakan perintah berikut untuk menandatangani file JAR:
jarsigner -keystore my_keystore.store \ -signedjar signthisclass_signed.jar \ -sigalg sha512withrsa \ -storetype CloudHSM \ -J-classpath '-J/opt/cloudhsm/java/*:/usr/lib/jvm/java-1.8.0/lib/tools.jar' \ -J-Djava.library.path=/opt/cloudhsm/lib \ signthisclass.jar
<key pair label>
Gunakan perintah berikut untuk memverifikasi JAR yang ditandatangani:
jarsigner -verify \ -keystore my_keystore.store \ -sigalg sha512withrsa \ -storetype CloudHSM \ -J-classpath '-J/opt/cloudhsm/java/*:/usr/lib/jvm/java-1.8.0/lib/tools.jar' \ -J-Djava.library.path=/opt/cloudhsm/lib \ signthisclass_signed.jar
<key pair label>
Masalah diketahui
Daftar berikut menyediakan daftar masalah yang diketahui saat ini.
-
Ketika menghasilkan kunci menggunakan keytool, penyedia pertama dalam konfigurasi penyedia tidak boleh CaviumProvider.
-
Ketika menghasilkan kunci menggunakan keytool, penyedia pertama (yang didukung) dalam file konfigurasi keamanan digunakan untuk menghasilkan kunci. Ini umumnya adalah penyedia perangkat lunak. Kunci yang dihasilkan kemudian diberikan alias dan diimpor ke AWS CloudHSM HSM sebagai kunci persisten (token) selama proses penambahan kunci.
-
Saat menggunakan keytool dengan penyimpanan kunci AWS CloudHSM, jangan tentukan opsi
-providerName
,-providerclass
, atau-providerpath
pada baris perintah. Tentukan opsi ini dalam file penyedia keamanan seperti yang dijelaskan dalam Prasyarat penyimpanan kunci. -
Bila menggunakan kunci EC yang tidak dapat diekstrak melalui keytool dan Jarsigner, penyedia SunEC perlu dihapus/dinonaktifkan dari daftar penyedia dalam file java.security. Jika Anda menggunakan kunci EC yang dapat diekstrak melalui keytool dan Jarsigner, penyedia mengekspor bit kunci dari HSM AWS CloudHSM dan menggunakan kunci lokal untuk menandatangani operasi. Kami tidak menyarankan Anda menggunakan kunci yang dapat diekspor dengan keytool atau Jarsigner.
Mendaftarkan kunci yang sudah ada sebelumnya dengan penyimpananAWS CloudHSM kunci
Untuk keamanan maksimum dan fleksibilitas dalam atribut dan pelabelan, kami sarankan Anda membuat kunci tanda tangan menggunakan key_mgmt_util. Anda juga dapat menggunakan aplikasi Java untuk menghasilkan kunci dalam AWS CloudHSM.
Bagian berikut menyediakan contoh kode yang menunjukkan bagaimana cara menghasilkan pasangan kunci baru pada HSM dan mendaftarkannya menggunakan kunci yang ada yang diimpor ke penyimpanan kunci AWS CloudHSM. Kunci yang diimpor tersedia untuk digunakan dengan alat pihak ketiga seperti keytool dan Jarsigner.
Untuk menggunakan kunci yang sudah ada sebelumnya, modifikasi sampel kode untuk mencari kunci dengan label bukannya menghasilkan kunci baru. Contoh kode untuk mencari kunci berdasarkan label tersedia di KeyUtilitiesRunner.java
penting
Mendaftarkan kunci yang disimpan di AWS CloudHSM dengan penyimpanan kunci lokal tidak mengekspor kunci. Ketika kunci terdaftar, penyimpanan kunci mendaftar alias kunci (atau label) dan menghubungkan objek sertifikat yang disimpan secara lokal dengan pasangan kunci pada AWS CloudHSM. Selama pasangan kunci dibuat sebagai tidak dapat diekspor, bit kunci tidak akan meninggalkan HSM.
// // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software // without restriction, including without limitation the rights to use, copy, modify, // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // package com.amazonaws.cloudhsm.examples; import com.cavium.key.CaviumKey; import com.cavium.key.parameter.CaviumAESKeyGenParameterSpec; import com.cavium.key.parameter.CaviumRSAKeyGenParameterSpec; import com.cavium.asn1.Encoder; import com.cavium.cfm2.Util; import javax.crypto.KeyGenerator; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.math.BigInteger; import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.KeyStore.PasswordProtection; import java.security.KeyStore.PrivateKeyEntry; import java.security.KeyStore.Entry; import java.util.Calendar; import java.util.Date; import java.util.Enumeration; // // KeyStoreExampleRunner demonstrates how to load a keystore, and associate a certificate with a // key in that keystore. // // This example relies on implicit credentials, so you must setup your environment correctly. // // https://docs.aws.amazon.com/cloudhsm/latest/userguide/java-library-install.html#java-library-credentials // public class KeyStoreExampleRunner { private static byte[] COMMON_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x03 }; private static byte[] COUNTRY_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x06 }; private static byte[] LOCALITY_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x07 }; private static byte[] STATE_OR_PROVINCE_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x08 }; private static byte[] ORGANIZATION_NAME_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x0A }; private static byte[] ORGANIZATION_UNIT_OID = new byte[] { (byte) 0x55, (byte) 0x04, (byte) 0x0B }; private static String helpString = "KeyStoreExampleRunner%n" + "This sample demonstrates how to load and store keys using a keystore.%n%n" + "Options%n" + "\t--help\t\t\tDisplay this message.%n" + "\t--store <filename>\t\tPath of the keystore.%n" + "\t--password <password>\t\tPassword for the keystore (not your CU password).%n" + "\t--label <label>\t\t\tLabel to store the key and certificate under.%n" + "\t--list\t\t\tList all the keys in the keystore.%n%n"; public static void main(String[] args) throws Exception { Security.addProvider(new com.cavium.provider.CaviumProvider()); KeyStore keyStore = KeyStore.getInstance("CloudHSM"); String keystoreFile = null; String password = null; String label = null; boolean list = false; for (int i = 0; i < args.length; i++) { String arg = args[i]; switch (args[i]) { case "--store": keystoreFile = args[++i]; break; case "--password": password = args[++i]; break; case "--label": label = args[++i]; break; case "--list": list = true; break; case "--help": help(); return; } } if (null == keystoreFile || null == password) { help(); return; } if (list) { listKeys(keystoreFile, password); return; } if (null == label) { label = "Keystore Example Keypair"; } // // This call to keyStore.load() will open the pkcs12 keystore with the supplied // password and connect to the HSM. The CU credentials must be specified using // standard CloudHSM login methods. // try { FileInputStream instream = new FileInputStream(keystoreFile); keyStore.load(instream, password.toCharArray()); } catch (FileNotFoundException ex) { System.err.println("Keystore not found, loading an empty store"); keyStore.load(null, null); } PasswordProtection passwd = new PasswordProtection(password.toCharArray()); System.out.println("Searching for example key and certificate..."); PrivateKeyEntry keyEntry = (PrivateKeyEntry) keyStore.getEntry(label, passwd); if (null == keyEntry) { // // No entry was found, so we need to create a key pair and associate a certificate. // The private key will get the label passed on the command line. The keystore alias // needs to be the same as the private key label. The public key will have ":public" // appended to it. The alias used in the keystore will We associate the certificate // with the private key. // System.out.println("No entry found, creating..."); KeyPair kp = generateRSAKeyPair(2048, label + ":public", label); System.out.printf("Created a key pair with the handles %d/%d%n", ((CaviumKey) kp.getPrivate()).getHandle(), ((CaviumKey) kp.getPublic()).getHandle()); // // Generate a certificate and associate the chain with the private key. // Certificate self_signed_cert = generateCert(kp); Certificate[] chain = new Certificate[1]; chain[0] = self_signed_cert; PrivateKeyEntry entry = new PrivateKeyEntry(kp.getPrivate(), chain); // // Set the entry using the label as the alias and save the store. // The alias must match the private key label. // keyStore.setEntry(label, entry, passwd); FileOutputStream outstream = new FileOutputStream(keystoreFile); keyStore.store(outstream, password.toCharArray()); outstream.close(); keyEntry = (PrivateKeyEntry) keyStore.getEntry(label, passwd); } long handle = ((CaviumKey) keyEntry.getPrivateKey()).getHandle(); String name = keyEntry.getCertificate().toString(); System.out.printf("Found private key %d with certificate %s%n", handle, name); } private static void help() { System.out.println(helpString); } // // Generate a non-extractable / non-persistent RSA keypair. // This method allows us to specify the public and private labels, which // will make KeyStore alises easier to understand. // public static KeyPair generateRSAKeyPair(int keySizeInBits, String publicLabel, String privateLabel) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { boolean isExtractable = false; boolean isPersistent = false; KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("rsa", "Cavium"); CaviumRSAKeyGenParameterSpec spec = new CaviumRSAKeyGenParameterSpec(keySizeInBits, new BigInteger("65537"), publicLabel, privateLabel, isExtractable, isPersistent); keyPairGen.initialize(spec); return keyPairGen.generateKeyPair(); } // // Generate a certificate signed by a given keypair. // private static Certificate generateCert(KeyPair kp) throws CertificateException { CertificateFactory cf = CertificateFactory.getInstance("X509"); PublicKey publicKey = kp.getPublic(); PrivateKey privateKey = kp.getPrivate(); byte[] version = Encoder.encodeConstructed((byte) 0, Encoder.encodePositiveBigInteger(new BigInteger("2"))); // version 1 byte[] serialNo = Encoder.encodePositiveBigInteger(new BigInteger(1, Util.computeKCV(publicKey.getEncoded()))); // Use the SHA512 OID and algorithm. byte[] signatureOid = new byte[] { (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x0D }; String sigAlgoName = "SHA512WithRSA"; byte[] signatureId = Encoder.encodeSequence( Encoder.encodeOid(signatureOid), Encoder.encodeNull()); byte[] issuer = Encoder.encodeSequence( encodeName(COUNTRY_NAME_OID, "<Country>"), encodeName(STATE_OR_PROVINCE_NAME_OID, "<State>"), encodeName(LOCALITY_NAME_OID, "<City>"), encodeName(ORGANIZATION_NAME_OID, "<Organization>"), encodeName(ORGANIZATION_UNIT_OID, "<Unit>"), encodeName(COMMON_NAME_OID, "<CN>") ); Calendar c = Calendar.getInstance(); c.add(Calendar.DAY_OF_YEAR, -1); Date notBefore = c.getTime(); c.add(Calendar.YEAR, 1); Date notAfter = c.getTime(); byte[] validity = Encoder.encodeSequence( Encoder.encodeUTCTime(notBefore), Encoder.encodeUTCTime(notAfter) ); byte[] key = publicKey.getEncoded(); byte[] certificate = Encoder.encodeSequence( version, serialNo, signatureId, issuer, validity, issuer, key); Signature sig; byte[] signature = null; try { sig = Signature.getInstance(sigAlgoName, "Cavium"); sig.initSign(privateKey); sig.update(certificate); signature = Encoder.encodeBitstring(sig.sign()); } catch (Exception e) { System.err.println(e.getMessage()); return null; } byte [] x509 = Encoder.encodeSequence( certificate, signatureId, signature ); return cf.generateCertificate(new ByteArrayInputStream(x509)); } // // Simple OID encoder. // Encode a value with OID in ASN.1 format // private static byte[] encodeName(byte[] nameOid, String value) { byte[] name = null; name = Encoder.encodeSet( Encoder.encodeSequence( Encoder.encodeOid(nameOid), Encoder.encodePrintableString(value) ) ); return name; } // // List all the keys in the keystore. // private static void listKeys(String keystoreFile, String password) throws Exception { KeyStore keyStore = KeyStore.getInstance("CloudHSM"); try { FileInputStream instream = new FileInputStream(keystoreFile); keyStore.load(instream, password.toCharArray()); } catch (FileNotFoundException ex) { System.err.println("Keystore not found, loading an empty store"); keyStore.load(null, null); } for(Enumeration<String> entry = keyStore.aliases(); entry.hasMoreElements();) { System.out.println(entry.nextElement()); } } }