簡體   English   中英

生成沒有外部庫的自簽名證書

[英]Generating self-signed certificate without external libraries

我很想知道是否有一種簡單的方法來創建一個與下面的New-SelfSignedCertificate命令相當的自簽名證書(例如,其他提供者也可以)。 我想只使用沒有P / Invoke的.NET庫或Bouncy Castle等外部庫,或者不使用應用程序中的PowerShell。

New-SelfSignedCertificate -DnsName $certificateName -CertStoreLocation $certificateStore -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certificateNotAfter

我想最簡單的替代方法是調用PowerShell或使用Nuget庫,如Bouncy Castle,如果沒有外部設施這是不可行的? 雖然感覺就像我知道如何構建證書,但是可以創建一個字節數組模板等,並在X509Certificate2構造函數中使用它。

似乎有人需要

public X509Certificate2 GenerateCertificate(string fileName, string password, string subjectName, StoreName storeName, DateTime endDate, DateTime notAfter, string provider = "Microsoft Enhanced RSA and AES Cryptographic Provider")
{
    //Could provider be taken from https://stackoverflow.com/questions/43474902/generate-self-signed-rsa-2048-sha-256-certificate-pfx-file-using-openssl?            
    var newCertificate = new X509Certificate2(fileName, password, X509KeyStorageFlags.Exportable);

     /*
      # The following creates a self-signed certificate with one year of running time.
     $currentDate = Get-Date
     $certificateEndDate = $currentDate.AddYears(1)
     $certificateNotAfter = $certificateEndDate.AddYears(1)

     $certificateName = "https://www.test.com/test"
     $certificateStore = "Cert:\LocalMachine\My"
     New-SelfSignedCertificate -DnsName $certificateName -CertStoreLocation $certificateStore -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certificateNotAfter
     */
}

<編輯:很快就發現使用普通的.NET沒有一個好方法。

我發現了一些選項:

一篇博客文章由Steve Syfuhs 在.NET中創建權威簽名和自簽名證書以及使用Mono擴展的另一篇SO帖子, Mono.Security不會設置多個KeyUsages 除了已經討論過的選擇之外,還有“像這樣的東西”。

在任何已發布的.NET版本中都沒有創建證書。

.NET Core 2.0 (尚未發布,但應該很快)已經 和.NET Framework 4.7.2通過CertificateRequest添加了此功能(一種可以執行自簽名證書,鏈式簽名證書或PKCS#10的API)證書/認證簽名請求)。

PowerShell命令結合了三件事:

  • 密鑰存儲參數(CSP)
  • 證書創建
  • 證書存儲(要添加證書的商店)

要在localhost上創建適用於TLS服務器身份驗證的“少量裝飾”自簽名證書,請執行以下操作:

X509Certificate2 certificate = null;
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName("localhost");

// New .NET Core Create(int) method.  Or use
// rsa = RSA.Create(), rsa.KeySize = newRsaKeySize,
// or (on .NET Framework) new RSACng(newRsaKeySize)
using (RSA rsa = RSA.Create(newRsaKeySize))
{
    var certRequest = new CertificateRequest(
        $"CN=localhost",
        rsa,
        HashAlgorithmName.SHA256,
        RSASignaturePadding.Pkcs1);

    // Explicitly not a CA.
    certRequest.CertificateExtensions.Add(
        new X509BasicConstraintsExtension(false, false, 0, false));

    certRequest.CertificateExtensions.Add(
        new X509KeyUsageExtension(
            X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment,
            true));

    // TLS Server EKU
    certRequest.CertificateExtensions.Add(
        new X509EnhancedKeyUsageExtension(
            new OidCollection
            {
                new Oid("1.3.6.1.5.5.7.3.1"),
            },
            false));

    // Add the SubjectAlternativeName extension
    certRequest.CertificateExtensions.Add(sanBuilder.Build());

    DateTimeOffset now = DateTimeOffset.UtcNow;
    certificate = certRequest.CreateSelfSigned(now, now.AddDays(365.25));
}

這個創建的證書有一個短暫的私鑰 - 它當前沒有寫入磁盤。 如果您不關心它使用的密鑰存儲提供商那么此時您最好的選擇是將證書(和私鑰)導出為PFX / PKCS#12,然后使用PersistKeySet重新導入(和Exportable ,因為你想要的,並將導入的副本添加到您選擇的X509Store。

如果您關心密鑰存儲提供程序(在您的情況下是CAPI CSP),或者您想要避免導出/導入,則可以使用預先保留的密鑰創建它。 所以你RSA.Create(newRsaKeySize)代替

CAPI:

var cspParameters = new CspParameters(
    /* PROV_RSA_AES */ 24,
    "Microsoft Enhanced RSA and AES Cryptographic Provider",
    Guid.NewGuid().ToString());

using (RSA rsa = new RSACryptoServiceProvider(newRsaKeySize, cspParameters))

CNG:

var keyParams = new CngKeyCreationParameters();
keyParams.Parameters.Add(
    new CngProperty(
        "Length",
        BitConverter.GetBytes(newRsaKeySize),
        CngPropertyOptions.Persist));

using (CngKey rsaKey = CngKey.Create(CngAlgorithm.RSA, Guid.NewGuid().ToString(), keyParams)
using (RSA rsa = new RSACng(rsaKey))

然后以通常的方式將其添加到打開的X509Store實例中。

感覺就像我知道如何構建證書一樣,可以創建一個字節數組模板等,並在X509Certificate2構造函數中使用它。

真正。 但這有點棘手。 您需要學習ASN.1( ITU-T X.680 ),DER( ITU-T X.690 )和X.509( RFC 5280ITU-T X.509 )。 如果你想創建與私鑰配對的證書,那么你需要學習PFX / PKCS#12( RFC 7292 ,雖然僅限於一些較舊的選項,除非你只有Win10)並且有一堆先決條件知識。

我認為這些都是有趣的東西需要學習,並且要知道好的事情......但是當我開始在白板上塗鴉DER時,我的同事給了我奇怪的外觀,所以我可能並不代表開發人員對“有趣”的一般看法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM