Menggunakan Client SDK 3 untuk berintegrasi dengan Java Keytool dan Jarsigner - AWS CloudHSM

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

AWS CloudHSM key store adalah toko kunci JCE tujuan khusus yang menggunakan sertifikat yang terkait dengan kunci pada HSM Anda melalui alat pihak ketiga seperti dan. keytool jarsigner AWS CloudHSM tidak menyimpan sertifikat di HSM, karena sertifikat bersifat publik, data non-rahasia. Toko AWS CloudHSM kunci menyimpan sertifikat dalam file lokal dan memetakan sertifikat ke kunci yang sesuai di HSM Anda.

Saat Anda menggunakan toko AWS CloudHSM kunci untuk menghasilkan kunci baru, tidak ada entri yang dihasilkan di file penyimpanan kunci lokal — kunci dibuat di HSM. Demikian pula, ketika Anda menggunakan penyimpanan kunci AWS CloudHSM untuk mencari kunci, pencarian diteruskan ke HSM. Ketika Anda menyimpan sertifikat di toko AWS CloudHSM kunci, penyedia memverifikasi bahwa key pair dengan alias yang sesuai ada di HSM, dan kemudian mengaitkan sertifikat yang disediakan dengan key pair yang sesuai.

Prasyarat

Untuk menggunakan penyimpanan AWS CloudHSM kunci, Anda harus terlebih dahulu menginisialisasi dan mengkonfigurasi AWS CloudHSM JCE SDK.

Langkah 1: Instal JCE

Untuk menginstal JCE, termasuk prasyarat AWS CloudHSM klien, ikuti langkah-langkah untuk menginstal perpustakaan 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 AWS CloudHSM kunci 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 toko AWS CloudHSM kunci. Untuk informasi tambahan, lihat artikel tentang Menggunakan AWS CloudHSM Key Store.

Langkah 3: Mendaftarkan penyedia JCE

Untuk mendaftarkan penyedia JCE, dalam CloudProvider konfigurasi Java.

  1. Buka file konfigurasi java.security di instalasi Java Anda, untuk mengedit.

  2. 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 menentukan opsi baris perintah saat membuat kunci dengan penyimpanan AWS CloudHSM kunci, itu akan menyebabkan kesalahan.

Menggunakan AWS CloudHSM key store dengan keytool

Keytool adalah utilitas baris perintah populer untuk kunci umum dan sertifikat tugas pada sistem Linux. Tutorial lengkap tentang keytool ada di luar lingkup dokumentasi AWS CloudHSM . Artikel ini menjelaskan parameter spesifik yang harus Anda gunakan dengan berbagai fungsi keytool saat memanfaatkan AWS CloudHSM sebagai akar kepercayaan melalui toko AWS CloudHSM kunci.

Saat menggunakan keytool dengan penyimpanan AWS CloudHSM kunci, tentukan argumen berikut ke perintah keytool apa pun:

-storetype CLOUDHSM \ -J-classpath '-J/opt/cloudhsm/java/*' \ -J-Djava.library.path=/opt/cloudhsm/lib

Jika Anda ingin membuat file penyimpanan kunci baru menggunakan toko AWS CloudHSM kunci, lihatMenggunakan AWS CloudHSM KeyStore. 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, toko AWS CloudHSM kunci akan membuat 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 AWS CloudHSM sebagai kunci persisten yang dapat diekstraksi.

Petunjuk untuk membuat kunci yang tidak dapat diekstraksi langsung pada HSM, dan kemudian menggunakannya dengan keytool atau Jarsigner, ditampilkan dalam contoh kode di Mendaftarkan Kunci yang Sudah Ada dengan Key Store. 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 yang dapat diekstrak melalui keytool dan jarsigner, penyedia mengekspor kunci dari AWS CloudHSM dan kemudian menggunakan kunci secara lokal untuk operasi penandatanganan.

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 key store 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 ED p256 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.

Hapus kunci menggunakan keytool

Toko AWS CloudHSM kunci tidak mendukung penghapusan kunci. Untuk menghapus kunci, Anda harus menggunakan deleteKey fungsi AWS CloudHSM alat baris perintah,deleteKey.

Hasilkan 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 tentang mengimpor data keystore, lihat Mengimpor sertifikat Intermediate dan root ke AWS CloudHSM Key Store menggunakan Keytool.

Menggunakan keytool untuk mengimpor sertifikat perantara dan root ke dalam penyimpanan AWS 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 instance klien ke AWS CloudHSM klaster Anda, mengimpor sertifikat pada penyimpanan kunci satu instans klien tidak akan secara otomatis membuat sertifikat tersedia pada instance klien lainnya. Anda harus mengimpor sertifikat pada setiap instans klien.

Menggunakan keytool untuk menghapus sertifikat dari toko AWS 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 instance klien ke AWS CloudHSM klaster Anda, menghapus sertifikat pada penyimpanan kunci satu instans klien tidak akan secara otomatis menghapus sertifikat dari instance klien lainnya. Anda harus menghapus sertifikat pada setiap instans klien.

Mengimpor sertifikat kerja ke toko AWS 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 sebelumnya dengan Key Store. 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 toko AWS CloudHSM kunci dengan jarsigner

Jarsigner adalah utilitas baris perintah populer untuk menandatangani file JAR menggunakan kunci yang disimpan dengan aman di 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 AWS CloudHSM sebagai akar 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:

  1. Ikuti petunjuk diPrasyarat penyimpanan kunci AWS CloudHSM.

  2. Siapkan kunci penandatanganan Anda dan sertifikat terkait serta rantai sertifikat yang harus disimpan di penyimpanan AWS CloudHSM kunci server atau instance klien saat ini. Buat kunci pada AWS CloudHSM dan kemudian impor metadata terkait ke toko AWS CloudHSM kunci Anda. Gunakan contoh kode dalam Mendaftarkan Kunci yang sudah ada sebelumnya dengan AWS CloudHSM Key Store untuk mengimpor metadata ke toko 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.

  3. Seluruh rantai sertifikat harus dapat diverifikasi. Agar rantai sertifikat dapat diverifikasi, Anda mungkin perlu menambahkan sertifikat CA dan sertifikat perantara ke toko AWS CloudHSM kunci. Lihat cuplikan kode di Menandatangani file JAR menggunakan AWS CloudHSM dan Jarsigner untuk instruksi tentang penggunaan kode Java untuk memverifikasi rantai sertifikat. Jika mau, Anda dapat menggunakan keytool untuk mengimpor sertifikat. Untuk petunjuk tentang penggunaan keytool, lihat Menggunakan Keytool untuk mengimpor sertifikat perantara dan root ke AWS CloudHSM Key Store.

Menandatangani file JAR menggunakan AWS 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 yang diketahui

Daftar berikut menyediakan daftar masalah yang diketahui saat ini.

  • Saat membuat kunci menggunakan keytool, penyedia pertama dalam konfigurasi penyedia tidak bisa 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 diberi alias dan diimpor ke AWS CloudHSM HSM sebagai kunci persisten (token) selama proses penambahan kunci.

  • Saat menggunakan keytool dengan AWS CloudHSM key store, jangan tentukan-providerName,-providerclass, atau -providerpath opsi 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 AWS CloudHSM HSM dan menggunakan kunci secara lokal untuk operasi penandatanganan. Kami tidak menyarankan Anda menggunakan kunci yang dapat diekspor dengan keytool atau Jarsigner.

Mendaftarkan kunci yang sudah ada sebelumnya dengan toko AWS 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 cara menghasilkan key pair baru pada HSM dan mendaftarkannya menggunakan kunci yang ada yang diimpor ke toko AWS CloudHSM kunci. 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 KeyUtilitiesRunnersampel.java pada GitHub.

penting

Mendaftarkan kunci yang disimpan AWS CloudHSM dengan toko 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()); } } }