9

ユーザーがブラウザーに保存されているデジタル証明書を使用して接続するC#Webアプリがあります。

これまで見てきた例から、SSLを有効にすると、Request.ClientCertificateを使用して証明書のフィールドにアクセスし、ユーザーの名前を確認できるため、IDの確認が簡単になります。

ただし、ユーザーから送信されたデータ(いくつかの単純なフィールドとバイナリファイル)に署名して、どのユーザーがデータベースの各レコードに入力したかを確実に証明できるようにすることも求められています。

私たちの最初の考えは、フィールド(および可能であればファイルのmd5)を含む小さなテキスト署名を作成し、証明書の秘密鍵で暗号化することでしたが...

私の知る限り、証明書の秘密鍵にアクセスしてデータに署名することはできません。また、ブラウザのフィールドに署名する方法があるかどうかもわかりません。または、Javaを使用する以外に選択肢はありません。アプレット。後者の場合、どのように実行しますか(使用できるオープンソースアプレットはありますか?自分で作成した方がよいでしょうか?)

もちろん、ユーザーの証明書からアクセスできるデータを使用して、サーバーで受信したフィールドに「署名」する方法があればもっと良いでしょう。しかし、そうでない場合は、問題を解決するための最良の方法に関する情報をいただければ幸いです。

4

4 に答える 4

8

java-appletを使用することをお勧めします。このアプローチは、すべてのブラウザーで統一されています。私たちはそれを私たちのプロジェクトで使用しています。ユーザーデータに署名するには、JCA API( http://download.oracle.com/javase/1.4.2/docs/guide/security/CryptoSpec.html#Signature )を使用する必要があります。また、JavaからWindows証明書ストアにアクセスする際の問題を解決する必要があります。

あなたはこの方法でそれを解決することができます:

KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");

keystore.load(null, null);

HashMap<String,String> userPublicKeys = new HashMap<String,String>();

Enumeration<String> aliasesEnum = keystore.aliases();

if (!aliasesEnum.hasMoreElements())
    throw new Exception("No certificate!");

// list through windows personal store
while (aliasesEnum.hasMoreElements()) 
{
   String alias = aliasesEnum.nextElement();

   boolean isKey = keystore.isKeyEntry(alias);

   if (isKey)
   {
       BASE64Encoder encoder = new BASE64Encoder();
       encoder.encode(keystore.getCertificate(alias).getEncoded());

       userPublicKeys.put(alias, encoder.encode(keystore.getCertificate(alias).getEncoded()));
       System.out.println("Entry alias: " + alias); 
   }

   // sign
   PrivateKey privateKey = (PrivateKey) keystore.getKey(alias,null);           

   Provider provider = keystore.getProvider();
   // data to signed
   byte[] data ="test data".getBytes();
   // Signing the data
   Signature sig = Signature.getInstance("SHA1withRSA", provider);
   sig.initSign(privateKey);

   sig.update(data);
   byte[] signature = sig.sign();

   System.out.println(ByteArrayToFromHexDigits.bytesToHexString(signature).toUpperCase());
}
于 2010-10-11T11:17:08.713 に答える
2

これが十分に強力な「署名」であるかどうかを法務部門に問い合わせる必要がありますが、フィールドを投稿するたびに、サーバーにフィールド値とクライアント証明書のハンドシェイクからの証明書のフィンガープリントを記録させます。はい、これは「偽造可能」です。指紋の知識がある人なら誰でもデータベースに偽のレコードを作成できますが、適切なデータベースセキュリティを使用すると、攻撃のベクトルを削除して、誰が何を投稿したかを記録できます(指紋を偽造できないため) SSLの双方向認証でのクライアント証明書の使用)

于 2010-10-05T13:04:24.540 に答える
1

クライアント証明書を使用して任意のテキストに署名できるJavaScriptメソッドcrypto.signTextがあります。ここにいくつかのドキュメント署名されたフォームの例があります。現在、Firefoxのみがサポートしているようです。

IEの場合、CAPICOM ActiveXオブジェクトがあります(MSからダウンロードできます)。使用例を次に示します。

さまざまなブラウザやOSバージョンでのこれらの機能のサポートについてはよくわかりません。おそらく、構成を確認する必要があります。

于 2010-10-10T20:16:05.067 に答える
1

証明書の秘密鍵にアクセスしてデータに署名することはできません。

これが当てはまらない場合、サーバーは証明書自体を記憶し、他のサービスを使用するときにそれを使用して実際のクライアントであるように見せることができます。

つまり、クライアントを認証するためのクライアント証明書の使用を完全に無効にします。

ブラウザのフィールドに署名する方法があるかどうかはわかりませんが、

適切なオーディエンスを獲得するために、適切なクライアント側タグ(JavaScript、ブラウザーなど)を使用してこの質問をするのはどうですか。(ブラウザ拡張機能またはActiveXオブジェクトを使用して実行できると確信していますが、それ自体に問題が発生します。)

于 2010-10-05T08:44:53.297 に答える