2016-04-29 69 views
5

我有下面的代碼生成一個很好的自簽名的證書,工程巨大,但我想更新到最新的BouncyCastle的(1.8.1.0),我很擔心過時的使用越來越警告:如何在不使用過時的BouncyCastle 1.7.0代碼的情況下生成自簽名證書?

var persistedCertificateFilename = "ClientCertificate.pfx"; 
if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["PersistedCertificateFilename"])) { persistedCertificateFilename = ConfigurationManager.AppSettings["PersistedCertificateFilename"].Trim(); } 
if (persistCertificateToDisk) 
{ 
    if (File.Exists(persistedCertificateFilename)) 
    { 
     var certBytes = File.ReadAllBytes(persistedCertificateFilename); 
       this.clientCertificate = new X509Certificate2(certBytes, (string) null, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); 
    } 
} 

if (this.clientCertificate == null) 
{ 
    // Initialize the new secure keys 
    KeyGenerator keyGenerator = KeyGenerator.Create(); 
    KeyPair keyPair = keyGenerator.GenerateKeyPair(); 
    this.privateKey = keyPair.ToEncryptedPrivateKeyString(privateKeySecret); 
    this.publicKey = keyPair.ToPublicKeyString(); 

    // Client certificate permissions 
    var certificatePermissions = new ArrayList() 
    { 
     KeyPurposeID.IdKPCodeSigning, 
     KeyPurposeID.IdKPServerAuth, 
     KeyPurposeID.IdKPTimeStamping, 
     KeyPurposeID.IdKPOcspSigning, 
     KeyPurposeID.IdKPClientAuth 
    }; 

    // Initialize the certificate generation 
    var certificateGenerator = new X509V3CertificateGenerator(); 
    BigInteger serialNo = BigInteger.ProbablePrime(128, new Random()); 
    certificateGenerator.SetSerialNumber(serialNo); 
    certificateGenerator.SetSubjectDN(GetLicenseeDN()); 
    certificateGenerator.SetIssuerDN(GetLicencerDN()); 
    certificateGenerator.SetNotAfter(DateTime.Now.AddYears(100)); 
    certificateGenerator.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0))); 
    //ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", keyPair.PrivateKey); // ?? 
    certificateGenerator.SetSignatureAlgorithm("SHA512withRSA"); 
    certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(certificatePermissions)); 
    var subjectKeyIdentifier = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.PublicKey)); 
    certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier); 
    certificateGenerator.SetPublicKey(keyPair.PublicKey); 
    var result = certificateGenerator.Generate(keyPair.PrivateKey); 
    var secure = new SecureString(); 
    foreach (char c in privateKeySecret) 
    { 
     secure.AppendChar(c); 
    } 

    X509KeyStorageFlags flags = X509KeyStorageFlags.MachineKeySet; 
    if (persistCertificateToDisk) { flags |= X509KeyStorageFlags.Exportable; flags |= X509KeyStorageFlags.PersistKeySet; } 
    this.clientCertificate = new X509Certificate2(Org.BouncyCastle.Security.DotNetUtilities.ToX509Certificate(result).Export(X509ContentType.Cert), secure, flags); 

    // This section allows us to use this certificate on Azure (no file access required) 
    CspParameters cspParams; 
    const int PROVIDER_RSA_FULL = 1; 
    cspParams = new CspParameters(PROVIDER_RSA_FULL); 
    cspParams.KeyContainerName = new Guid().ToString(); 
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 
    cspParams.ProviderName = "Microsoft Strong Cryptographic Provider"; 
    var rule = new CryptoKeyAccessRule("everyone", CryptoKeyRights.FullControl, AccessControlType.Allow); 
    cspParams.CryptoKeySecurity = new CryptoKeySecurity(); 
    cspParams.CryptoKeySecurity.SetAccessRule(rule); 

    // Set the private key 
    var tempRcsp = (RSACryptoServiceProvider) Org.BouncyCastle.Security.DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters) keyPair.PrivateKey); 
    var rcsp = new RSACryptoServiceProvider(cspParams); 
    rcsp.ImportCspBlob(tempRcsp.ExportCspBlob(true)); 
    this.clientCertificate.PrivateKey = rcsp; 

    if (persistCertificateToDisk) 
    { 
     if (!File.Exists(persistedCertificateFilename)) 
     { 
      File.WriteAllBytes(persistedCertificateFilename, this.clientCertificate.Export(X509ContentType.Pkcs12, (string) null)); 
     } 
    } 
} 

具體地,警告是:

'X509V3CertificateGenerator.SetSignatureAlgorithm(字符串)' 是 過時: '中不需要如果具有ISignatureFactory生成用於'

'X509V3CertificateGenerator.Generate(AsymmetricKeyParameter)' 是 過時: '使用產生具有ISignatureFactory'

所以,我的問題是:

  1. 我是否需要擔心關於這些警告?
  2. 如果是這樣,哪條線改變?
  3. 如果我更新此代碼,是否有性能優勢?

注意:如果任何一個奇怪的原因,我堅持這盤是此代碼創建了一個證書的每個客戶端被實例化時,這是特別苛刻,由於最小密鑰長度爲2048和1.7.0的表現。

回答

8

我也爲此付出了一段時間。 我終於有這個解決方案。 讓我們的錯誤之一:

'X509V3CertificateGenerator.Generate(AsymmetricKeyParameter)' is obsolete: 'Use Generate with an ISignatureFactory' 

你基本上是使用(我在做同樣的事情)的生成方法是這樣的:

var certificate = certificateGenerator.Generate(issuerCertificate.PrivateKey, random); 

其中certificateGeneratorCertificateContainer 類的實例錯誤地說:'Use Generate with an ISignatureFactory'
因此,這讓我們首先創建一個實例給ISIGNatureFactory。

ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random); 

而對於這此之前正常工作,你也應該聲明如下:

var randomGenerator = new CryptoApiRandomGenerator(); 
var random = new SecureRandom(randomGenerator); 
AsymmetricCipherKeyPair subjectKeyPair = default(AsymmetricCipherKeyPair); 
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); 

keyPairGenerator.Init(keyGenerationParameters); 
subjectKeyPair = keyPairGenerator.GenerateKeyPair(); 
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair; 

而現在這些變化後,該方法Generate從改變:

var certificate = certificateGenerator.Generate(issuerCertificate.PrivateKey, random); 

到:

var certificate = certificateGenerator.Generate(signatureFactory); 

我希望它有幫助。

+0

工作完美!謝謝! – djbyter

+0

Thanx的反饋。 – drgmak

+0

我在嘗試使用該解決方案時遇到問題。在代碼中沒有提及keystrenght變量,我決定使用任意整數值來查看我應該使用哪一個。但是,我有一個例外:system arithmeticexception bit.length <2 bouncy castle big integer –

相關問題