/
GostCryptoProvider.cs
147 lines (125 loc) · 4.9 KB
/
GostCryptoProvider.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
141
142
143
144
145
146
147
using System;
using System.Collections.Generic;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using CryptoPro.Sharpei;
using CryptoPro.Sharpei.Xml;
using Microsoft.Xades;
using Org.BouncyCastle.X509;
using Xades.Abstractions;
using Xades.Helpers;
using Xades.Models;
namespace Xades.Implementations
{
public class GostCryptoProvider : ICryptoProvider
{
private Dictionary<string, string> HashAlgorithmMap { get; set; }
public GostCryptoProvider()
{
HashAlgorithmMap = new Dictionary<string, string>
{
{ "http://www.w3.org/2001/04/xmldsig-more#gostr3411", "GOST3411" }
};
}
public HashAlgorithm GetHashAlgorithm(string algorithm)
{
string algorithmName;
var algorithmUrl = algorithm;
if (!HashAlgorithmMap.TryGetValue(algorithmUrl, out algorithmName))
{
return null;
}
var pkHash = HashAlgorithm.Create(algorithmName);
return pkHash;
}
private int _referenceIndex;
public string SignatureMethod
{
get
{
return CPSignedXml.XmlDsigGost3410UrlObsolete;
}
}
public string DigestMethod
{
get
{
return CPSignedXml.XmlDsigGost3411UrlObsolete;
}
}
public AsymmetricAlgorithm GetAsymmetricAlgorithm(X509Certificate2 certificate, string privateKeyPassword)
{
var provider = (Gost3410CryptoServiceProvider)certificate.PrivateKey;
if (!string.IsNullOrEmpty(privateKeyPassword))
{
var secureString = new SecureString();
foreach (var chr in privateKeyPassword)
secureString.AppendChar(chr);
provider.SetContainerPassword(secureString);
}
return provider;
}
public Reference GetReference(string signedElementId, string signatureId)
{
var reference = new Reference
{
Uri = string.Format("#{0}",signedElementId),
DigestMethod = DigestMethod,
Id = string.Format("{0}-ref{1}", signatureId, _referenceIndex)
};
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
_referenceIndex++;
return reference;
}
public AsymmetricSignatureFormatter GetSignatureFormatter(X509Certificate2 certificate)
{
if (certificate.PrivateKey is Gost3410CryptoServiceProvider)
{
#pragma warning disable 612
var signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName(CPSignedXml.XmlDsigGost3410UrlObsolete);
#pragma warning restore 612
return signatureDescription.CreateFormatter(certificate.PrivateKey);
}
throw new NotSupportedException("Неизвестный тип закрытого ключа");
}
public XadesObject GetXadesObject(XadesInfo xadesInfo, string signatureId)
{
var xadesObject = new XadesObject
{
QualifyingProperties = new QualifyingProperties
{
Target = string.Format("#{0}",signatureId),
SignedProperties = new SignedProperties { Id = string.Format("{0}-signedprops", signatureId) }
}
};
var hashAlgorithm = GetHashAlgorithm();
var hashValue = hashAlgorithm.ComputeHash(xadesInfo.RawCertData);
var x509CertificateParser = new X509CertificateParser();
var bouncyCert = x509CertificateParser.ReadCertificate(xadesInfo.RawCertData);
var cert = new Cert
{
IssuerSerial = new IssuerSerial
{
X509IssuerName = bouncyCert.IssuerDN.ToX509IssuerName(),
X509SerialNumber = bouncyCert.SerialNumber.ToString()
},
CertDigest =
{
DigestValue = hashValue,
DigestMethod = new DigestMethod { Algorithm = DigestMethod }
}
};
var signedSignatureProperties = xadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties;
signedSignatureProperties.SigningCertificate.CertCollection.Add(cert);
signedSignatureProperties.SigningTime = xadesInfo.SigningDateTimeUtc.ToDateTimeOffset(xadesInfo.TimeZoneOffsetMinutes);
return xadesObject;
}
private static HashAlgorithm GetHashAlgorithm()
{
return HashAlgorithm.Create("GOST3411");
}
}
}