-
Notifications
You must be signed in to change notification settings - Fork 41
/
SignedXmlKeyContainerTest.cs
140 lines (112 loc) · 5.14 KB
/
SignedXmlKeyContainerTest.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;
using GostCryptography.Base;
using GostCryptography.Gost_R3410;
using GostCryptography.Tests.Properties;
using GostCryptography.Xml;
using NUnit.Framework;
namespace GostCryptography.Tests.Xml.Sign
{
/// <summary>
/// Подпись и проверка подписи XML-документа с использованием контейнера ключей.
/// </summary>
/// <remarks>
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием контейнера ключей,
/// а затем проверяет полученную цифровую подпись.
/// </remarks>
[TestFixture(Description = "Подпись и проверка подписи XML-документа с использованием контейнера ключей")]
public class SignedXmlKeyContainerTest
{
[Test]
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
public void ShouldSignXmlWithGost_R3410_2001(TestCertificateInfo testCase)
{
// Given
var certificate = testCase.Certificate;
var keyContainer = certificate.GetPrivateKeyInfo();
var signingKey = new Gost_R3410_2001_AsymmetricAlgorithm(keyContainer);
var xmlDocument = CreateXmlDocument();
// When
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2001_KeyValue(signingKey));
// Then
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
}
[Test]
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
public void ShouldSignXmlWithGost_R3410_2012_256(TestCertificateInfo testCase)
{
// Given
var certificate = testCase.Certificate;
var keyContainer = certificate.GetPrivateKeyInfo();
var signingKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
var xmlDocument = CreateXmlDocument();
// When
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2012_256_KeyValue(signingKey));
// Then
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
}
[Test]
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
public void ShouldSignXmlWithGost_R3410_2012_512(TestCertificateInfo testCase)
{
// Given
var certificate = testCase.Certificate;
var keyContainer = certificate.GetPrivateKeyInfo();
var signingKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(keyContainer);
var xmlDocument = CreateXmlDocument();
// When
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2012_512_KeyValue(signingKey));
// Then
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
}
private static XmlDocument CreateXmlDocument()
{
var document = new XmlDocument();
document.LoadXml(Resources.SignedXmlExample);
return document;
}
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, GostKeyValue keyValue)
{
var signingKey = keyValue.PublicKey;
// Создание подписчика XML-документа
var signedXml = new GostSignedXml(xmlDocument);
// Установка ключа для создания подписи
signedXml.SigningKey = signingKey;
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(signingKey) };
// Установка ссылки на узел
signedXml.AddReference(dataReference);
// Установка информации о ключе, который использовался для создания подписи
var keyInfo = new KeyInfo();
keyInfo.AddClause(keyValue);
signedXml.KeyInfo = keyInfo;
// Вычисление подписи
signedXml.ComputeSignature();
// Получение XML-представления подписи
var signatureXml = signedXml.GetXml();
// Добавление подписи в исходный документ
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
return xmlDocument;
}
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
{
// Создание подписчика XML-документа
var signedXml = new GostSignedXml(signedXmlDocument);
// Поиск узла с подписью
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
// Загрузка найденной подписи
signedXml.LoadXml((XmlElement)nodeList[0]);
// Проверка подписи
return signedXml.CheckSignature();
}
private static string GetDigestMethod(GostAsymmetricAlgorithm signingKey)
{
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
using (var hashAlgorithm = signingKey.CreateHashAlgorithm())
{
return hashAlgorithm.AlgorithmName;
}
}
}
}