Эта статья содержит варианты использования секретных ключей, которые имеют пароль при их использовании в PKCS #7/CMS.

Способы использования

  1. При подписи сообщения использовать метод CmsSigner.ComputeSignature(CmsSigner signer,bool silent) со вторым параметром установленным в false. В этом случае при каждой подписи будет появляться окно КриптоПро для ввода пароля.

  2. Убрать с контейнера пароль при помощи контрольной панели КриптоПро CSP. Этот метод, кроме очевидной меньшей защищенности, еще не работает для носителей с аппаратным PIN кодом (eToken, ruToken, Оскар...).

  3. Открыть контейнер с секретным ключем заранее и не закрывать его пока не будут выполнены все необходимы операции подписи. Данный вариант удобен, если необходимо подписать несколько "документов" на одном ключе. Есть несколько способов этого добиться.

    1. Есть сертификат certificate в MY со ссылкой на секретный ключ

      C# Copy imageCopy Code
      Gost3410CryptoServiceProvider prov = (Gost3410CryptoServiceProvider)certificate.PrivateKey;
      SecureString s = new SecureString();
      // заполняем пароль... например так
      s.AppendChar('1');
      // и передаем его в провайдер.
      prov.SetContainerPassword(s);
                                      

      если необходимо, то можно сразу и проверить пароль, например, так

      C# Copy imageCopy Code
      byte[] dummyHash = new byte[32];
      p.SignHash(dummyHash);
                                      

      если он не подпойдет, то будет выведено окно КриптоПро с просьбой ввести другой пароль. При необходимости используем этот сертификат со ссылкой на уже открытый и прогруженный ключ.

    2. Есть сертификат (где-то) и есть секретный ключ (ему соответствующий)

      C# Copy imageCopy 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 imageCopy Code
      byte[] dummyHash = new byte[32];
      prov.SignHash(dummyHash);
                                      

      и связываем сертификат с уже открытым секретным ключем и при необходимости используем этот сертификат со ссылкой на уже открытый и прогруженный ключ.

    3. Есть сертификат certificate в MY со ссылкой на секретный ключ. Этот метод вариация на предидущий, только параметры контейнера мы получаем из ссылки на секретный ключ при помощи кода:

      C# Copy imageCopy Code
      CspKeyContainerInfo info = ((ICspAsymmetricAlgorithm)certificate.PrivateKey).CspKeyContainerInfo;
                                      

См. также