Статус: Сотрудник
Группы: Участники
Зарегистрирован: 20.02.2017(UTC) Сообщений: 218
Сказал(а) «Спасибо»: 4 раз Поблагодарили: 63 раз в 59 постах
|
Можно, но очень аккуратно. CSP использует пины только при открытии контейнера с ключом. Контейнер закрывается когда мы зовём dispose. Можно dispose'ить контейнер и открывать его при каждый подписи. Для этого нужно сделать using на закрытый ключ. Код:using (var keyToUse = SomeHowGetPrivateKey())
{
var sig1 = keyToUse.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
}
Важный момент - когда вы зовёте Dispose на ключ (неявно при закрытии using), контейнер закрывается и ссылка на этот ключ портится. Т.е. если использовать Код:using (var keyToUse = cert.PrivateKey as Gost3410_2012_256CryptoServiceProvider)
{
var sig1 = keyToUse.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
}
using (var keyToUse = cert.PrivateKey as Gost3410_2012_256CryptoServiceProvider)
{
var sig2 = keyToUse.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
}
вторая подпись не пройдёт с ошибкой, ибо контейнер с ключом уже закрыт, объект сертификата однако всё ещё содержит на него ссылку. Отсюда придётся каждый раз создавать объект сертификата для каждый подписи Код:using(var cert = var cert = store.Certificates.Find(X509FindType.FindBySubjectName, "testCertWithContainer", false)[0])
{
using (var keyToUse = cert.PrivateKey as Gost3410_2012_256CryptoServiceProvider)
{
var sig = keyToUse1.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
}
}
или использовать что то такое хитрое Код: CspParameters cspParameters;
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
// Открываем хранилище и читаем параметры сертификата
store.Open(OpenFlags.ReadOnly);
using (var cert = store.Certificates.Find(X509FindType.FindBySubjectName, "testCertWithContainer", false)[0])
{
using (var cert_key = cert.PrivateKey as Gost3410_2012_256CryptoServiceProvider)
{
cspParameters = new CspParameters();
//копируем параметры csp из исходного контекста сертификата
cspParameters.KeyContainerName = cert_key.CspKeyContainerInfo.KeyContainerName;
cspParameters.ProviderType = cert_key.CspKeyContainerInfo.ProviderType;
cspParameters.ProviderName = cert_key.CspKeyContainerInfo.ProviderName;
cspParameters.Flags = cert_key.CspKeyContainerInfo.MachineKeyStore
? (CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore)
: (CspProviderFlags.UseExistingKey);
} // закрываем контейнер
} // закрываем сертификат
}
using (var keyToUse = new Gost3410_2012_256CryptoServiceProvider(cspParameters))
{
// Так как контейнер закрыт - открываем его и запрашиваем пин-код
var sig1 = keyToUse.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
// конетейнер открыт, пин не запросится
var sig2 = keyToUse.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
} // закрываем контейнер
using (var keyToUse1 = new Gost3410_2012_256CryptoServiceProvider(cspParameters))
{
// Так как контейнер закрыт - открываем его и запрашиваем пин-код
var sig1 = keyToUse1.SignData(new byte[] { 0, 0, 0, 0 }, new Gost3411_2012_256CryptoServiceProvider());
}
Отредактировано пользователем 19 ноября 2020 г. 13:59:27(UTC)
| Причина: Не указана |
|