Эта статья содержит варианты использования секретных ключей, которые имеют пароль при их использовании в PKCS #7/CMS.
Способы использования
При подписи сообщения использовать метод CmsSigner.ComputeSignature(CmsSigner signer,bool silent) со вторым параметром установленным в false. В этом случае при каждой подписи будет появляться окно КриптоПро для ввода пароля.
Убрать с контейнера пароль при помощи контрольной панели КриптоПро CSP. Этот метод, кроме очевидной меньшей защищенности, еще не работает для носителей с аппаратным PIN кодом (eToken, ruToken, Оскар...).
Открыть контейнер с секретным ключем заранее и не закрывать его пока не будут выполнены все необходимы операции подписи. Данный вариант удобен, если необходимо подписать несколько "документов" на одном ключе. Есть несколько способов этого добиться.
Есть сертификат certificate в MY со ссылкой на секретный ключ
C# Copy Code Gost3410CryptoServiceProvider prov = (Gost3410CryptoServiceProvider)certificate.PrivateKey; SecureString s = new SecureString(); // заполняем пароль... например так s.AppendChar('1'); // и передаем его в провайдер. prov.SetContainerPassword(s);
если необходимо, то можно сразу и проверить пароль, например, так
C# Copy Code byte[] dummyHash = new byte[32]; p.SignHash(dummyHash);
если он не подпойдет, то будет выведено окно КриптоПро с просьбой ввести другой пароль. При необходимости используем этот сертификат со ссылкой на уже открытый и прогруженный ключ.
Есть сертификат (где-то) и есть секретный ключ (ему соответствующий)
C# Copy Code CspParameters pars = new CspParameters(75, null, "test33"); // если необходимо запретить вывод окна и при неправильном пароле получить ошибку, запрещаем окна pars.Flags = CspProviderFlags.NoPrompt; SecureString s = new SecureString(); // заполняем пароль... например так s.AppendChar('1'); pars.KeyPassword = s; Gost3410CryptoServiceProvider prov = new Gost3410CryptoServiceProvider(pars);
если необходимо проверить корректность пароля делаем как уже было сделано выше
C# Copy Code byte[] dummyHash = new byte[32]; prov.SignHash(dummyHash);
и связываем сертификат с уже открытым секретным ключем и при необходимости используем этот сертификат со ссылкой на уже открытый и прогруженный ключ.
Есть сертификат certificate в MY со ссылкой на секретный ключ. Этот метод вариация на предидущий, только параметры контейнера мы получаем из ссылки на секретный ключ при помощи кода:
C# Copy Code CspKeyContainerInfo info = ((ICspAsymmetricAlgorithm)certificate.PrivateKey).CspKeyContainerInfo;