2012-05-11 5 views
8

私たちは文書管理システムを作成しており、Webクライアントを使用して文書にデジタル署名を行いたいと考えています。当社のJavaクライアントアプリケーションは、すでにデジタル署名を適用して確認することができますが、当社のWebクライアントでも署名を作成したいと考えています。これはGWTで書かれているため、クライアント側で実行するとJavaScriptアプリケーションです。スマートカードを使用してWebアプリケーション(JavaScript)でデジタル署名を作成する方法は?

Javaアプレットを作成してクライアントにダウンロードして実行することは望ましくありません。ドキュメントに署名するために、ブラウザセキュリティデバイスまたはブラウザAPIを使用したいと考えています。また、完全なドキュメントサーバー側を維持し、ドキュメントハッシュのみをクライアントに移動したいと考えています。

私たちは、これがNSSまたはNPAPI /のNPRuntimeを使用して可能であるべき感じるが、我々はこのことについての任意の情報を見つけることができませんでした。 (ちなみに、npruntimeはIEでも利用できますか?IEで同じ結果を得るためにActiveXを使用する必要がありますか?)

ご意見はありますか?

答えて

9

私はその答えを見つけた。 MozillaはNSSモジュールの一部をwindow.cryptoオブジェクトでエクスポートします。このような操作を行う標準的な方法は、おそらくDOMCrypt経由であり、現在はdiscusses in W3Cです。 Google Chrome開発者はDOMCryptを標準化するためにW3Cを待つが、MicrosoftはActiveXオブジェクトas explained hereを使用する必要がある(これはWindowsのFirefox/Chrome/Operaでも有効)。

+0

* DOMCrypt * linkは、想定されていないものです。 – ares

+0

おかげさまで、DOMcrypt.orgのDNSは別の所有者に割り当てられているようです。私は非常に似た内容の別のページへのリンクを変更しました。 – eppesuig

+0

Firefox 33の後にwindow.cryptoが[削除されました](https://wiki.mozilla.org/SecurityEngineering/Removing_Proprietary_window.crypto_Functions)されていませんか? – marcellorvalle

0

Win/IEでは、CAPICOM http://en.wikipedia.org/wiki/CAPICOMをサードパーティのActiveXまたは外部ライブラリなしで使用することができます。
IEがインストールされている場所であればどこでも動作します。
しかしこれは廃止されています。

以下は、私がIEにサインインするために使用しているものです。私はこれを例えば:var signature = signDigest(stringToBeSigned);と呼びます。

function signDigest(text) { 
if (window.event) 
    window.event.cancelBubble = true; 

var dest = sign(text); //TODO 

return dest; 
} 

// CAPICOM constants 

var CAPICOM_STORE_OPEN_READ_ONLY = 0; 
var CAPICOM_CURRENT_USER_STORE = 2; 
var CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0; 
var CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY = 6; 
var CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9; 
var CAPICOM_CERTIFICATE_FIND_KEY_USAGE = 12; 
var CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE = 0x00000080; 
var CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0; 
var CAPICOM_INFO_SUBJECT_SIMPLE_NAME = 0; 
var CAPICOM_ENCODE_BASE64 = 0; 
var CAPICOM_E_CANCELLED = -2138568446; 
var CERT_KEY_SPEC_PROP_ID = 6; 

function IsCAPICOMInstalled() { 
    if (typeof (oCAPICOM) == "object") { 
     if ((oCAPICOM.object != null)) { 
      // We found CAPICOM! 
      return true; 
     } 
    } 
} 

function FindCertificateByHash() { 

    try { 
     // instantiate the CAPICOM objects 
     var MyStore = new ActiveXObject("CAPICOM.Store"); 
     // open the current users personal certificate store 
     MyStore.Open(CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY); 

     // find all of the certificates that have the specified hash 
     var FilteredCertificates = MyStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, strUserCertigicateThumbprint); 

     var Signer = new ActiveXObject("CAPICOM.Signer"); 
     Signer.Certificate = FilteredCertificates.Item(1); 
     return Signer; 

     // Clean Up 
     MyStore = null; 
     FilteredCertificates = null; 
    } 
    catch (e) { 
     if (e.number != CAPICOM_E_CANCELLED) { 
      return new ActiveXObject("CAPICOM.Signer"); 
     } 
    } 
} 

function sign(src) { 
    if (window.crypto && window.crypto.signText) 
     return sign_NS(src); 
    else 

     return sign_IE(src); 
} 

function sign_NS(src) { 
    var s = crypto.signText(src, "ask"); 
    return s; 
} 

function sign_IE(src) { 
    try { 
     // instantiate the CAPICOM objects 
     var SignedData = new ActiveXObject("CAPICOM.SignedData"); 
     var TimeAttribute = new ActiveXObject("CAPICOM.Attribute"); 

     // Set the data that we want to sign 
     SignedData.Content = src; 
     var Signer = FindCertificateByHash(); 


     // Set the time in which we are applying the signature 
     var Today = new Date(); 
     TimeAttribute.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME; 
     TimeAttribute.Value = Today.getVarDate(); 
     Today = null; 
     Signer.AuthenticatedAttributes.Add(TimeAttribute); 

     // Do the Sign operation 
     var szSignature = SignedData.Sign(Signer, true, CAPICOM_ENCODE_BASE64); 
     return szSignature; 
    } 
    catch (e) { 
     if (e.number != CAPICOM_E_CANCELLED) { 
      alert("An error occurred when attempting to sign the content, the error was: " + e.description); 
     } 
    } 
    return ""; 
} 

私はなど、エンコーディングでいくつかの問題を持っていたので、私は今、あなたはそれを行うことができ、私のコントローラ(.NET)だけでなく

 byte[] decbuff = Convert.FromBase64String(signature); 


    //CAPICOM USES 16 BIT ENCODING 
    Encoding utf16Enc = Encoding.GetEncoding("UTF-16LE"); 


    byte[] utf16Data = utf16Enc.GetBytes(getContent); 


    ContentInfo content = new ContentInfo(utf16Data); 

    System.Security.Cryptography.Pkcs.SignedCms cms = new System.Security.Cryptography.Pkcs.SignedCms(content,true); 
    cms.Decode(decbuff); 

    int length = decbuff.Length;   

    X509Certificate2 cert = cms.SignerInfos[0].Certificate; 


    X509Chain chain = new X509Chain(); 
    bool theVal = chain.Build(cert); 
    cms.CheckHash();  
    cms.CheckSignature(false); 
+0

私はCAPICOMを使ってxmlにX509Certificate2記号で署名しています。店舗から証明書を選択すると、その証明書のユーザー名とパスワードを入力するよう求められません。上のコードと同じ状況ですか? – SeaSide

+0

「messed up」の場合にのみ - ブラウザを閉じて開いて、資格情報を要求します。私はときどきそれが尋ねるのを止めるポイントを得るが、ブラウザを再ロードすることは常にこれを修正するようだ。 – Yablargo

-1

が含まれています。 PKCS#11スマートカードまたはトークンに基づくWebアプリケーションは、SilverlightバージョンのNCryptokiを使用して実装できます。

1)NCryptokiのSilverlightのバージョンを使用し、11の機能は、によって提供されるPKCS#を使用して、あなたのロジック、あなたのケースでデジタル署名を実装する独自のSilverlightユーザーコントロールを開発:あなたは2 chanchesを持ってhttp://www.ncryptoki.com

を参照してください。 jQueryプラグインを使用して、スマートカード )は上記のSilverlightのバージョンに基づいており、

また、JavaScriptでPKCS#11関数を呼び出してJavaScriptでアプリケーションを実装する、あなたはNDigitSignのSilverlightのバージョンを使用することができます(再び見ますhttp://www.ncryptoki.com)それはあなたが必要とするすべてを行い、どのWebブラウザでも実装できます。

+0

このソリューションをご利用いただきありがとうございます。私はncryptokiプロジェクトを認識していませんでしたが、Silverlightベースのため、クライアントマシン(Javaアプレットの場合)にソフトウェアをインストールする必要があります。さらに重要なのは、おそらくWindowsマシンでのみ動作するということです。最後に、PKCS#11を直接使用するアプリケーションを作成する必要があり、そのようなプログラムを避けたいと思っています。 – eppesuig

4

現在(2016年5月)は不可能です。

ChromeはJavaサポートを廃止しました。 'Windowsエッジ'は持っていません。 IE11のサポートは悪く、OracleはJavaプラグインを中止することに決めました。 Firefox、IEの古いバージョン、Javaプラグインでのみ可能です。

新しいWebCryptographyApi標準は、ブラウザ用のデジタル署名のサポートを提供しますが、それは、この解決するためにPCKS#11サポート

実電子政府ソリューションがない: 1)ユーザーのPC上のローカルのJavaアプリケーションをインストールします。アプリケーションはポートで、例えば5678 のようにリッスンします。2)ページ内で、javascriptはアプレットのサポートがあるかどうかを検出します。 3)サポートがない場合は、http://127.0.01:5678/signの形式でアプリケーションに接続し、 4)アプリケーションがローカルであると11のデジタル署名を作成ドライバのPKCS#を含むオペレーティング・システム・ストアを使用して支障がなく、定期的に結果を照会するJavaScript結果 5)ページを作成し、それを取得する準備ができたら

+0

JavaアプレットはJava Web Startから起動できます。これはすべてのデスクトップブラウザで機能しますが、いくつかの余分な努力が必要です。 –

+0

スペインでは、これを解決する電子政府のソリューションがあります。私は答えにそれを記録する – pedrofb

0

つ私が関わってきたプロジェクトChromeとネイティブメッセージングでこれをやった:

https://github.com/CACBridge/ChromeCAC

これはクロムのプラグインをインストールする必要が、それ以外は素晴らしい作品。例えば、事前にこれを行う必要があることがわかっているイントラネット/グループ環境。

関連する問題