CurrentUser/My および LocalMachine/My で証明書を列挙して使用 (署名) できるものを作成しようとしていますが、Windows 証明書ストアについては何も見つけることができず、Java 独自のシークレット ストアしか見つかりませんでした。 このリンクは有望に見えますが、Java に同梱されているものしか使用できません。
SO でこの質問が以前に出されたのを見つけましたが、それは 5 年前のもので、コンピューターの時代では長い年月です。ありがとう!
KeyStore keyStore = KeyStore.getInstance(getKeyStoreType(), "SunMSCAPI");
keyStore.load(null, null);
try {
Field field = keyStore.getClass().getDeclaredField("keyStoreSpi");
field.setAccessible(true);
KeyStoreSpi keyStoreVeritable = (KeyStoreSpi)field.get(keyStore);
field = keyStoreVeritable.getClass().getEnclosingClass().getDeclaredField("entries");
field.setAccessible(true);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Set accessible keyStoreSpi problem", e);
}
Enumeration enumeration = keyStore.aliases();
Java のクロスプラットフォームの性質には、独自の欠点があります。外部ライブラリがないと、OS 固有のものの一部 (または多く) にアクセスできません。Windows 証明書ストアには、Java のデフォルト インストールではサポートされていない CryptoAPI ネイティブ関数を介してのみアクセスできます。
このスレッドをご覧ください: Calling Win32 API method from Java
JNA を使用できる場合は、crypt32.dll でさまざまな証明書および証明書ストア関数を使用して、証明書を列挙し、署名操作を実行できます。
私は Crypt32 が残した場所から選び、JNA を使用して、Windows 固有のプログラムを使用する場合にポップアップする同じ Windows ダイアログを使用して証明書にアクセスしました。
NativeLibrary cryptUI = NativeLibrary.getInstance("Cryptui");
NativeLibrary crypt32 = NativeLibrary.getInstance("Crypt32");
Function functionCertOpenSystemStore = crypt32.getFunction("CertOpenSystemStoreA");
Object[] argsCertOpenSystemStore = new Object[] { 0, "CA"};
HANDLE h = (HANDLE) functionCertOpenSystemStore.invoke(HANDLE.class, argsCertOpenSystemStore);
Function functionCryptUIDlgSelectCertificateFromStore = cryptUI.getFunction("CryptUIDlgSelectCertificateFromStore");
System.out.println(functionCryptUIDlgSelectCertificateFromStore.getName());
Object[] argsCryptUIDlgSelectCertificateFromStore = new Object[] { h, 0, 0, 0, 16, 0, 0};
Pointer ptrCertContext = (Pointer) functionCryptUIDlgSelectCertificateFromStore.invoke(Pointer.class, argsCryptUIDlgSelectCertificateFromStore);
Function functionCertGetNameString = crypt32.getFunction("CertGetNameStringW");
char[] ptrName = new char[128];
Object[] argsCertGetNameString = new Object[] { ptrCertContext, 5, 0, 0, ptrName, 128};
functionCertGetNameString.invoke(argsCertGetNameString);
System.out.println("Selected certificate is " + new String(ptrName));
Function functionCertFreeCertificateContext = crypt32.getFunction("CertFreeCertificateContext");
Object[] argsCertFreeCertificateContext = new Object[] { ptrCertContext};
functionCertFreeCertificateContext.invoke(argsCertFreeCertificateContext);
Function functionCertCloseStore = crypt32.getFunction("CertCloseStore");
Object[] argsCertCloseStore = new Object[] { h, 0};
functionCertCloseStore.invoke(argsCertCloseStore);
機能するのは単なるコードです。コーディング プラクティスを自由に適用してください。