Ну, большинство вопросов / ответов, которые я нашел здесь, касаются не кэширования PIN-кода смарт-карты, что является противоположным случаем того, что я ищу.
У нас есть консольное приложение, которое подписывает несколько хешей. Для этого мы используем Pkcs.CmsSigner , потому что нам нужно проверить подписанные хеши на стороне сервера.
Обычно ПИН-код смарт-карты должен автоматически кэшироваться в CSP для каждого процесса, а в Windows 7 это происходит, но если мы запускаем наш код в W10, это не так. Также мы поддерживаем сертификаты CNG и не-CNG.
Метод, который мы используем для подписи, следующий:
public string SignX509(string data, bool chkSignature, string timestampServer, X509Certificate2 selectedCertificate)
{
CmsSigner oSigner = null;
SignedCms oSignedData = null;
string hashText = String.Empty;
try
{
if (chkSignature)
{
oSigner = new CmsSigner();
oSigner.Certificate = selectedCertificate;
byte[] arrDataHashed = HashSHA1(data);
// hash the text to sign
ContentInfo info = new ContentInfo(arrDataHashed);
// put the hashed data into the signedData object
oSignedData = new SignedCms(info);
if (string.IsNullOrEmpty(timestampServer)) {
oSigner.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.Now));
}
else {
TimeStampToken tsToken = GetTSAToken(arrDataHashed, timestampServer);
AsnEncodedData timeData = new Pkcs9AttributeObject(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdAASigningCertificate.Id, tsToken.GetEncoded());
oSigner.UnsignedAttributes.Add(timeData);
oSigner.SignedAttributes.Add(new Pkcs9SigningTime(tsToken.TimeStampInfo.GenTime.ToLocalTime()));
}
// sign the data
oSignedData.ComputeSignature(oSigner, false);
hashText = Convert.ToBase64String(oSignedData.Encode());
}
else
{
// just clean the hidden hash text
hashText = String.Empty;
}
}
catch (Exception ex)
{
Console.WriteLine("ERRNO [" + ex.Message + " ]");
return null;
}
return hashText;
}
То, что мы пробовали до сих пор:
- Использование RSACryptoServiceProvider для явного сохранения ключ в CSP
RSACryptoServiceProvider key = (RSACryptoServiceProvider)cmsSigner.Certificate.PrivateKey;
key.PersistKeyInCsp = true;
Это работает, если мы используем метод SignHa sh, но, как я уже говорил, нам нужно проверить подписали данные на стороне сервера, и у нас нет доступа к сертификату, поэтому нам нужен конверт PKCS. Если я установлю это bool и подпишу, используя код CMS, то поведение будет таким же.
Установка PIN-кода программно Другой попыткой была установка PIN-кода программно через CryptoContext на основе этого ответа :
private void SetPinForPrivateKey(X509Certificate2 certificate, string pin) {
if (certificate == null) throw new ArgumentNullException("certificate");
var key = (RSACryptoServiceProvider)certificate.PrivateKey;
var providerHandle = IntPtr.Zero;
var pinBuffer = System.Text.Encoding.ASCII.GetBytes(pin);
// provider handle is implicitly released when the certificate handle is released.
SafeNativeMethods.Execute(() => SafeNativeMethods.CryptAcquireContext(ref providerHandle,
key.CspKeyContainerInfo.KeyContainerName,
key.CspKeyContainerInfo.ProviderName,
key.CspKeyContainerInfo.ProviderType,
SafeNativeMethods.CryptContextFlags.Silent));
SafeNativeMethods.Execute(() => SafeNativeMethods.CryptSetProvParam(providerHandle,
SafeNativeMethods.CryptParameter.KeyExchangePin,
pinBuffer, 0));
SafeNativeMethods.Execute(() => SafeNativeMethods.CertSetCertificateContextProperty(
certificate.Handle,
SafeNativeMethods.CertificateProperty.CryptoProviderHandle,
0, providerHandle));
}
При таком подходе Я могу отключить запрос PIN-кода, программно установив PIN-код . Проблема в том, что Мне нужно прочитать PIN-код в первый раз, чтобы я мог установить его в последующих подписях.
Я пытался прочитать PIN-код из приглашения, используя CryptoGetProvParam с dwParam PP_ADMIN_PIN и PP_KEYEXCHANGE_PIN, но безуспешно. Вот мои две догадки:
- Я не читаю в нужное время или в нужном направлении
- CMS использует другой обработчик внутри
Вопрос 1:
Можно ли прочитать PIN-код, указанный в приглашении Windows?
Вопрос 2:
Если считывание ПИН-кода невозможно, есть ли другой способ форсировать кеширование ПИН-кода?