X509Certificate и XMLDSig

#c# #x509certificate #signature #xml-signature

#c# #x509certificate #подпись #xml-подпись

Вопрос:

Мне нужно в C # (4.0) подписать XML (конверт XMLDSig), используя X509Certificate (файл .p7b, предоставленный тем, который должен проверять подпись) У меня нет опыта в области безопасности, мои знания ограничиваются некоторыми базовыми понятиями о криптографии.

Вот что я сделал:

1) Я установил сертификат в: Сертификаты — Текущий пользователь — Доверенная корневая сертификация.

2) из .net я успешно загрузил сертификат с помощью этого кода:

 X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
try
{
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, certName, false);
    if (certs.Count == 0)
        return null;

    return certs[0];
}
finally
{
    store.Close();
}
  

3) Я попытался использовать открытый ключ сертификата для создания подписи с помощью следующего кода;

 XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
var reader = new StringReader(xml);
doc.Load(reader);
var signedXml = new SignedXml(doc);
X509Certificate2 certificate = this.GetCertificateFromStore(certName); // the previous code
signedXml.SigningKey = (RSACryptoServiceProvider)certificate.PublicKey.Key;
var reference = new Reference();
reference.Uri = "";
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
signedXml.AddReference(reference);
signedXml.ComputeSignature(); //  exception!!!
var element = signedXml.GetXml();
doc.AppendChild(doc.ImportNode(element, true));
  

но при вычислении подписи я получаю исключение: «Объект содержит только открытую половину пары ключей. Также должен быть предоставлен закрытый ключ «.

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

Чего мне не хватает?

Заранее спасибо

Ответ №1:

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

Комментарии:

1. В моем случае у меня есть приложение, которому необходимо отправить XML в службу поддержки клиентов. Я полагаю, что клиент хотел бы знать, что отправителю (мне) можно доверять (или, возможно, другим приложениям). Они дали мне .p7b, который будет использоваться для подписи xml. Как вы думаете, нужно ли мне запрашивать privatekey (ключ, которым клиент мог бы поделиться с доверенными партнерами) или можно получить ту же задачу только с открытым ключом?

2. @SkyG Вы должны иметь свой собственный сертификат с закрытым ключом и передать этот сертификат (разумеется, без закрытого ключа) клиенту. Если заказчик вам дал это свидетельство, и попросил подписать данные с помощью этого сертификата, это может означать одно из следующего: (а) заказчик не понимает, как PKI работает, или (б) заказчик имел в виду, что вам нужно зашифровать данные (и это еще раз говорит о том, что клиент не компетентен в безопасности). Еще…

3. @SkyG Чтобы убедиться, что сертификат, который вы использовали для подписи, принадлежит вам, клиент проверяет сертификат. Это сложная процедура, автоматизированная в большинстве программ. Это работает, когда ваш сертификат подписан каким-либо известным центром сертификации. Например. если вы перейдете к globalsign.com/document-security-compliance/adobe-cds при покупке сертификата подписи PDF программа Adobe Reader клиента автоматически подтвердит правильность этого сертификата. То же самое работает с XML.

4. Спасибо, Евгений, тогда я начну читать больше о PKI :). Я хотел бы проголосовать за ответ, но у меня все еще недостаточно баллов для этого.

Ответ №2:

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

Этап проверки: верификатор расшифрует вашу подпись, используя ваш открытый ключ, и получит хэш H1. Затем исходное содержимое хэшируется получателем H1. Получатель проверяет, равен ли H1 H2, если нет, проверка подписи завершается ошибкой.