0

Я нашел отличный пример использования C# API BouncyCastle для создания сертификата CA и самозаверяющего сертификата.BouncyCastle Change KeySpec для AT_SIGNATURE

Однако мне нужно KeySpec = 2 (At_Signature для CERT_KEY_PROV_INFO_PROP_ID), а не KeySpec 0. Что в настоящее время предоставляет этот код:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 


//Downloaded using nuget, source: http://www.bouncycastle.org/csharp/ 
//Library is open-source. 

namespace CertificateToolLibrary 
{ 
using System; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 
using Org.BouncyCastle.Asn1; 
using Org.BouncyCastle.Asn1.X9; 
using Org.BouncyCastle.Asn1.Pkcs; 
using Org.BouncyCastle.Asn1.X509; 
using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Generators; 
using Org.BouncyCastle.Crypto.Parameters; 
using Org.BouncyCastle.Crypto.Prng; 
using Org.BouncyCastle.Math; 
using Org.BouncyCastle.OpenSsl; 
using Org.BouncyCastle.Pkcs; 
using Org.BouncyCastle.Security; 
using Org.BouncyCastle.Utilities; 
using Org.BouncyCastle.X509.Extension; 
using Org.BouncyCastle.X509; 

public class X509Certificate2Builder 
{ 
    public string SubjectName 
    { set { _subjectName = value; } } 

    public string SubjectAlternativeName 
    { set { _subjectAlternativeName = value; } } 

    public string IssuerName 
    { set { _issuerName = value; } } 

    public AsymmetricAlgorithm IssuerPrivateKey 
    { set { _issuerPrivateKey = value; } } 

    public X509Certificate2 Issuer 
    { 
     set 
     { 
      _issuer = value; 
      _issuerName = value.IssuerName.Name; 
      if (value.HasPrivateKey) 
       _issuerPrivateKey = value.PrivateKey; 
     } 
    } 

    public int? KeyStrength 
    { set { _keyStrength = value ?? 2048; } } 

    public DateTime? NotBefore 
    { set { _notBefore = value; } } 

    public DateTime? NotAfter 
    { set { _notAfter = value; } } 

    public bool Intermediate 
    { set { _intermediate = value; } } 

    private string _subjectName; 
    private string _subjectAlternativeName; 
    private X509Certificate2 _issuer; 
    private string _issuerName; 
    private AsymmetricAlgorithm _issuerPrivateKey; 
    private int _keyStrength = 2048; 
    private DateTime? _notBefore; 
    private DateTime? _notAfter; 
    private bool _intermediate = true; 

    public X509Certificate2 Build() 
    { 
     // Generating Random Numbers 
     var randomGenerator = new CryptoApiRandomGenerator(); 
     var random = new SecureRandom(randomGenerator); 

     // The Certificate Generator 
     var certificateGenerator = new X509V3CertificateGenerator(); 

     // Serial Number 
     var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random); 
     certificateGenerator.SetSerialNumber(serialNumber); 

     // Signature Algorithm 
     certificateGenerator.SetSignatureAlgorithm("SHA512WithRSA"); 

     // Issuer and Subject Name 
     certificateGenerator.SetIssuerDN(new X509Name(_issuerName ?? _subjectName)); 
     certificateGenerator.SetSubjectDN(new X509Name(_subjectName)); 

     //Subject Alternative Name 
     if (!(String.IsNullOrEmpty(_subjectAlternativeName))) 
     { 
      //Here we signify ip address instead of DNS SAN. This could be condition upon further development. 
      GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.IPAddress, _subjectAlternativeName)); 
      certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName); 
     } 

     // Authority Key Identifier 
     if (_issuer != null) 
     { 
      var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(DotNetUtilities.FromX509Certificate(_issuer)); 
      certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier); 

      //var subjectKeyIdentifier = new SubjectKeyIdentifier(DotNetUtilities.FromX509Certificate(_issuer)); 
      //certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier); 
      //certificateGenerator.addExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifierStructure(keyPair.getPublic())); 
     } 

     // Basic Constraints - certificate is allowed to be used as intermediate. 
     certificateGenerator.AddExtension(X509Extensions.BasicConstraints, false, new BasicConstraints(_intermediate)); 


     // Valid For 
     certificateGenerator.SetNotBefore(_notBefore ?? DateTime.UtcNow.Date.AddDays(-1)); 
     certificateGenerator.SetNotAfter(_notAfter ?? DateTime.UtcNow.Date.AddYears(3)); 


     //Key Usage(s) don't set for CA cert, just the SSL cert. 
     if (_subjectName != "CN=Bla Certificate Authority") 
     { 
      certificateGenerator.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment)); 
      var usages = new[] { KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth}; 
      certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(usages)); 
     } 


     // Subject Public Key 
     var keyGenerationParameters = new KeyGenerationParameters(random, _keyStrength); 
     var keyPairGenerator = new RsaKeyPairGenerator(); 
     keyPairGenerator.Init(keyGenerationParameters); 

     var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); 
     var issuerKeyPair = _issuerPrivateKey == null 
      ? subjectKeyPair 
      : DotNetUtilities.GetKeyPair(_issuerPrivateKey); 

     certificateGenerator.SetPublicKey(subjectKeyPair.Public); 

     //Add the subject key identifier for the SSL Certficate 
     if (_subjectName != "CN=Bla Certificate Authority") 
     { 
      certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(subjectKeyPair.Public)); 
     } 

     // selfsign certificate 
     var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random); 

     // merge into X509Certificate2 
     return new X509Certificate2(certificate.GetEncoded()) 
     { 
      PrivateKey = ConvertToRsaPrivateKey(subjectKeyPair) 
     }; 
    } 

    private static AsymmetricAlgorithm ConvertToRsaPrivateKey(AsymmetricCipherKeyPair keyPair) 
    { 
     var keyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private); 
     var seq = (Asn1Sequence)Asn1Object.FromByteArray(keyInfo.PrivateKey.GetDerEncoded()); 
     if (seq.Count != 9) 
      throw new PemException("malformed sequence in RSA private key"); 

     var rsa = new RsaPrivateKeyStructure(seq); 
     var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); 

     return DotNetUtilities.ToRSA(rsaparams); 



    } 
} 

}

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

Я полагаю, что использовать rsaparams как cspparams в родном коде C#, но я просто ничего не могу найти на нем.

Любая помощь была бы чрезвычайно оценена!

ответ

0

Заканчивать класс KeyUsage константы

Я думаю, что вы хотите использовать KeyUsage.keyEncipherment

+0

Да, если вы посмотрите в моем примере, я использую оба. – Mumbles76

+0

certificateGenerator.AddExtension (X509Extensions.KeyUsage, true, new KeyUsage (KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment)); var usages = new [] {KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth}; certificateGenerator.AddExtension (X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage (обычаи)); – Mumbles76

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/14025596) – maazza

0

Оказывается, что я был на рабочем столе развивающихся, и это KeySpec был установлен в 0. Однако, когда Я запустил мой инструмент на сервере 2012 года, keypec был установлен в 1. Я все настроен.

0
public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey) 
    { 
     var cspParams = new CspParameters 
     { 
      ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider", 
      ProviderType = 24, 
      KeyContainerName = KEY_CONTAINER_NAME, 
      KeyNumber = (int)KeyNumber.Signature, 
      Flags = CspProviderFlags.UseMachineKeyStore 
     }; 

     RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams); 

     RSAParameters parameters = new RSAParameters 
     { 
      Modulus = privateKey.Modulus.ToByteArrayUnsigned(), 
      P = privateKey.P.ToByteArrayUnsigned(), 
      Q = privateKey.Q.ToByteArrayUnsigned(), 
      DP = privateKey.DP.ToByteArrayUnsigned(), 
      DQ = privateKey.DQ.ToByteArrayUnsigned(), 
      InverseQ = privateKey.QInv.ToByteArrayUnsigned(), 
      D = privateKey.Exponent.ToByteArrayUnsigned(), 
      Exponent = privateKey.PublicExponent.ToByteArrayUnsigned() 
     }; 

     rsaProvider.ImportParameters(parameters); 

     return rsaProvider; 
    } 

Чтобы просто добавить еще один ответ, я смог заставить keypec = 2 AT_SIGNATURE использовать этот фрагмент. Но в настоящее время он сталкивается с проблемами при подписании. Просто хотел выбросить его туда, чтобы другие потенциально могли вести их в правильном направлении.

 Смежные вопросы

  • Нет связанных вопросов^_^