Лучший способ подписать данные в веб-форме с помощью сертификата пользователя - PullRequest
9 голосов
/ 15 июня 2010

У нас есть веб-приложение на C #, где пользователи будут подключаться с помощью цифрового сертификата, хранящегося в их браузерах.

Из примеров, которые мы видели, проверка их идентичности будет легкой после включения SSL, поскольку мы можем получить доступ к полям в сертификате, используя Request.ClientCertificate, чтобы проверить имя пользователя.

Однако нас также попросили подписать данные, отправленные пользователем (несколько простых полей и двоичный файл), чтобы мы могли без сомнения доказать, какой пользователь внес каждую запись в нашу базу данных.

Нашей первой мыслью было создание небольшой текстовой подписи, включающей поля (и, если возможно, md5 файла), и шифрование ее с помощью закрытого ключа сертификата, но ...

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

Конечно, было бы лучше, если бы былСпособ «подписать» поля, полученные на сервере, с использованием данных, к которым мы можем получить доступ из сертификата пользователя.Но если нет, то любая информация о наилучшем способе решения проблемы будет принята.

Ответы [ 4 ]

8 голосов
/ 11 октября 2010

Я предлагаю вам использовать java-апплет. Этот подход унифицирован для всех браузеров. Мы используем это в наших проектах. Для подписи пользовательских данных вам нужно будет использовать JCA API (http://download.oracle.com/javase/1.4.2/docs/guide/security/CryptoSpec.html#Signature).. Также вам нужно будет решить проблему с доступом к хранилищу сертификатов Windows из Java.

Вы можете решить это следующим образом:

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());
}
2 голосов
/ 05 октября 2010

Вам нужно будет спросить свой юридический отдел, достаточно ли это сильная «подпись», но при каждой публикации полей сервер должен записывать значения полей и отпечаток сертификата из рукопожатия клиентского сертификата. Да, это «подделка», так как любой, кто знает отпечаток пальца, может создать поддельную запись в базе данных, но при надлежащей защите базы данных вы можете удалить этот вектор атаки и получить запись о том, кто что опубликовал (так как вы не можете подделать отпечаток сертификата клиента в двухсторонней аутентификации SSL)

1 голос
/ 11 октября 2010

Существует метод JavaScript crypto.signText, который позволяет подписывать произвольный текст с помощью сертификата клиента.Вот некоторые документы и пример подписанной формы .Кажется, в настоящее время только Firefox поддерживает его.

Для IE существует объект ActiveX CAPICOM (доступный для загрузки из MS). Здесь является примером его использования.

Я не уверен насчет поддержки этих функций в разных версиях браузера и ОС, вам, вероятно, придется проверить его на предмет конфигурации.1011 *

1 голос
/ 05 октября 2010

мы не можем получить доступ к закрытому ключу сертификата для подписи данных,

Если это не так, то сервер может запомнить сам сертификат и использовать его для отображениябыть реальным клиентом при использовании других сервисов.

Т.е. полностью лишит законной силы использование клиентских сертификатов для аутентификации клиента.

, и я не знаю, есть ли способчтобы подписать поля в браузере,

Как насчет того, чтобы задать этот вопрос с помощью подходящих тегов на стороне клиента (например, JavaScript, Browser), чтобы получить нужную аудиторию.(Я уверен, что это можно сделать с помощью расширения браузера или объекта ActiveX, но это создает свои собственные проблемы.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...