2012-05-11 1 views
8

Мы создали систему управления документами и хотели бы подписывать документы в цифровом виде с помощью веб-клиента. Наше клиентское приложение Java уже может применять и проверять электронную подпись, но мы хотели бы сделать подпись даже с нашим веб-клиентом. Это написано в GWT, поэтому при запуске на стороне клиента это приложение для JavaScript.Как сделать цифровую подпись в веб-приложении (JavaScript) с помощью смарт-карты?

Мы не хотим создавать Java-апплет и загружать его на клиент и выполнять его. Мы хотим использовать устройство безопасности браузера или API-интерфейс браузера, чтобы подписать документ. Мы также хотели бы сохранить всю серверную часть документа и перенести на клиент только хэш документа.

Мы считаем, что это должно быть возможно с помощью NSS или NPAPI/npruntime, но мы не нашли никакой информации об этом. (Кстати, можно ли использовать npruntime также в IE? Должны ли мы использовать ActiveX для достижения того же результата с IE?)

Есть ли у вас какие-либо намеки?

ответ

9

После еще нескольких поисковых запросов я нашел ответ. Mozilla экспортирует часть своего модуля NSS через объект window.crypto. Более стандартный способ выполнения такой операции, вероятно, осуществляется через DOMCrypt, то есть в настоящее время discusses in W3C. Разработчик Google Chrome будет ждать W3C для стандартизации DOMCrypt, в то время как Microsoft требует использования объекта ActiveX as explained here (это работает даже с Firefox/Chrome/Opera в Windows).

+0

* Ссылка DOMCrypt * не является тем, чем должна быть. – ares

+0

Спасибо @ares, DNS DOMcrypt.org, похоже, теперь назначен другому владельцу. Я изменил ссылку на другую страницу с очень похожим контентом. – eppesuig

+0

window.crypto не был [удален] (https://wiki.mozilla.org/SecurityEngineering/Removing_Proprietary_window.crypto_Functions) после Firefox 33? – 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

Только иногда, если он «перепутался» - я закрываю браузер, открываю его и запрашивает учетные данные. Иногда я получаю точку, где она перестает спрашивать, но перезагрузка браузера всегда, кажется, исправляет это. – Yablargo

-1

Теперь вы можете сделать это. Веб-приложение на основе смарт-карт или токенов PKCS # 11 может быть реализовано с использованием версии Silverlight от NCryptoki. См http://www.ncryptoki.com

У вас есть два chanches:

1) с помощью Silverlight версии NCryptoki и развить свой собственный Silverlight пользовательский элемент управления, который реализует логику, цифровую подпись в вашем случае, с помощью PKCS # 11 функций, поставляемых смарт-карта

2), используя плагин JQuery на основе вышеприведенного Silverlight версии и реализовать приложение в JavaScript, вызывая PKCS # 11 функций в JavaScript

Кроме того, вы можете использовать Silverlight версию NDigitSign (см снова http://www.ncryptoki.com) который делает все, что вам нужно, и может быть реализован в любом веб-браузере.

+0

Спасибо за указание на это решение. Я не знал о проекте ncryptoki, но, поскольку он основан на Silverlight, он по-прежнему требует установки программного обеспечения на клиентской машине (что касается Java-апплета), и, что более важно, он, вероятно, будет работать только на машинах Windows. Наконец, для этого потребуется написать приложение, которое напрямую использует PKCS # 11, и мне бы очень хотелось избежать такой программы. – eppesuig

4

В настоящее время (май 2016 года) это невозможно.

Chrome отказался от поддержки Java. «Край Windows» не будет. Поддержка IE11 плоха, и Oracle решила отказаться от плагина java. Это возможно только с Firefox, более старыми версиями IE и плагином Java.

Новый стандарт WebCryptographyApi обеспечивает поддержку цифровой подписи для браузеров, но он не имеет pcks # 11 поддержки

Real электронной говермент решения для решения этой проблемы: 1) Установить локальное приложение Java на компьютере пользователя. Приложение прослушивает порт, например 5678 2) На вашей странице javascript обнаруживает, есть ли поддержка апплетов 3) Если поддержки нет, подключается к приложению в форме http://127.0.01:5678/sign и отправляет данные для подписи. 4) Приложение является локальным и не имеет никаких проблем с использованием операционной системы хранилища ключей, которая включает в себя драйвера PKCS # 11. Сделайте цифровую подпись и подготавливает 5) страницы результатов Javascript периодически запрашивать результат и получает его, когда готовы

+0

Java-приложения можно запускать через Java Web Start. Это работает во всех настольных браузерах, хотя необходимы некоторые дополнительные усилия. –

+0

В Испании есть решение в электронном правительстве решить это. Я опишу его в ответе – pedrofb

0

One проект, который я был связан с сделал это с Chrome и Native сообщений:

https://github.com/CACBridge/ChromeCAC

Это требует установки хромированной плагина, но в остальном работает отлично. Идеально подходит для, например, Intranet/Group, где вы знаете, что вам нужно будет это сделать раньше времени.