2011-06-27 18 views
2

証明書トークンを使用して文書に署名するJavaコードを開発しています。これまではすべてがうまくいっていますが、私はユーザーのピンを保存しているので、毎回入力する必要がないように「ピンの入力」ダイアログを表示しないようにしたいと考えています。ここでの本当の問題は、このコードがバッチモードで実行されることです(ユーザーとの対話なし)。いったんタイプされると、キーは記憶に残っているので、短時間のうちに再度タイプする必要はありません。しかし、私はそれに頼ることはできません、私はPINを提供する必要があります。私はおよそCryptSetProvParamPP_KEYEXCHANGE_PIN魔女は、溶液であってもよく聞いたことがあるSunMSCAPIで文書に署名し、「PINを入力」ダイアログを表示しない

protected KeyStore loadKeyStoreFromSmartCard() { 
    keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); 
    keyStore.load(null, null); 
    return keyStore; 
} 

public void signDocument(byte[] conteudoParaAssinar, String certAlias) { 
    char[] pass = (char[]) null; 
    PrivateKey key = (PrivateKey) loadKeyStoreFromSmartCard.getKey(certAlias, pass); 
    Certificate[] chain = loadKeyStoreFromSmartCard(true).getCertificateChain(certAlias); 
    CertStore certsAndCRLs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Arrays.asList(chain)), "BC"); 
    X509Certificate cert = (X509Certificate) chain[0]; 
    CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 
    gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA1); 
    gen.addCertificatesAndCRLs(certsAndCRLs); 
    CMSProcessable data = new CMSProcessableByteArray(conteudoParaAssinar); 
    CMSSignedData signed = gen.generate(data, true, "SunMSCAPI"); 
    byte[] envHex = signed.getEncoded(); 
} 

EDIT、しかし:ここでは、私がこれまで持っているコードは(それが唯一のサンプルである、それは完全でも仕事ではないかもしれません)私はjavaから呼び出す方法を知らない。私が見つけたすべての例は.netのためのものです。

答えて

3

私はこれを一度実行しましたが、残念なことにスマートカードドライバはバグだったので、ドライバはドライバ自体に実装されたネイティブのPINコールバックを時々発生させようとしました。しかし、あなたのドライバーがその点でより良くなると仮定しよう。

まず、CallbackHandlerを実装する必要があります。このドキュメントでは、概念の概要を説明しています。あなたのケースでは、処理するのが面白いのはPasswordCallbackケースです。

KeyStore.Entry ke = store.getEntry(alias, null); 
if (!(ke instanceof KeyStore.PrivateKeyEntry)) 
    throw new RuntimeException("The entry is not a private key."); 
PrivateKey key = ((KeyStore.PrivateKeyEntry) ke).getPrivateKey(); 

プロバイダが自動的に生成され、適切なPasswordCallback S:

次に、あなたのKeyStoreを秘密鍵にアクセスする(省略例外処理)次に

Provider provider = Security.getProvider("SunMSCAPI"); 
CallbackHandler cbh = // your implementation 
KeyStore.ProtectionParameter protection = new KeyStore.CallbackHandlerProtection(cbh); 
//get a handle of the CAPI KeyStore as before 
KeyStore.Builder keystoreBuilder = KeyStore.Builder.newInstance("Windows-MY", 
                   provider, 
                   protection); 
KeyStore store = keystoreBuilder.getKeyStore(); 

を、次のように、これを行うの作成しますCallbackHandlerに送信されます。コールバックを処理するときは、単にキャッシュされたパスワードを渡すだけです。

そのパスワードのキャッシュは、一般的に眉をひそめている言うまでもなく

;)

0

MS CryptoAPIは、PINを指定する統一方法を提供しません。あなたの唯一のオプションは、可能であればCyrptoAPIからPKCS#11に切り替えることです。PKCS#11では、コードでデバイスに「ログオン」し、PINにもPINを入力する必要があります。

更新:一部 CSP(暗号化サービスプロバイダ)いくつかのハードウェアベンダーによって出荷されたモジュールを使用すると、特別なCryptoAPI関数(CSPSetProvParam、http://msdn.microsoft.com/en-us/library/aa379858%28v=VS.85%29.aspx)を呼び出し、それにPINを渡すことができます。ハードウェアのCSPがPINを設定するこの方法をサポートしている場合は、ベンダーに連絡して、正確なパラメータIDなどを入力してください。

+0

theresのかもしれないコールバックを登録する方法はありませんか?私はPKCSを使用することはできません.. :( –

+0

@Rafael私は答えを更新しました。 –

関連する問題