web-dev-qa-db-fra.com

Générer un certificat auto-signé avec Root CA Signer

Scénario: J'utilise PowerShell sur Windows Server 2012r2 pour générer un certificat racine et je souhaite l'utiliser pour signer un certificat intermédiaire et Web nouvellement créé dans des environnements de développement/test générés (et détruits) dynamiques. Les scripts sont déployés à distance et le but est de le conserver si possible dans PowerShell. Sous Windows 10/2016, cela est relativement facile, après avoir généré le certificat racine:

$Cert = New-SelfSignedCertificate -Signer $Root -Subject "CN=$Subject"

J'ai généré le certificat racine à l'aide de COM X509Enrollment.CX509CertificateRequestCertificate et Security.Cryptography.X509Certificates.X509Certificate2 dans un PS bâtard que je possède depuis un certain temps, principalement parce que je devais m'assurer que le sujet et l'utilisation étaient définis très précisément. Je ne sais pas trop comment l'utiliser pour signer le certificat standard sans ce qui précède (ce que j'ai déjà utilisé).

Il existe quelques exemples utilisant Bouncy Castle (voir ci-dessous) en C # que je pourrais relier à PowerShell, mais il me faudrait ensuite le déployer également sur les environnements de développement/test dynamiques et je veux pouvoir le faire dans Powershell (via COM si nécessaire) avec le moins de dépendances.

4
LimpingNinja

La solution ultime dans mon cas, en évitant makecert et openssl, était d’utiliser Powershell et BouncyCastle. J'ai ajouté le repo PSBouncyCastle de PSBouncyCastle par RLipscombe et poussé 1.8.1 Bouncy Castle in. Ma version forked est celle que j'ai utilisée pour le script, elle se trouve dans Forked: PSBouncyCastle.New .

J'ai ensuite utilisé StackOverflow: C # Générer des certificats à la volée comme inspiration pour écrire le PowerShell suivant ci-dessous, Je vais l'ajouter à mon GitHub et le commenter, et je le modifierai dès que je le ferai :

Import-Module -Name PSBouncyCastle.New

function New-SelfSignedCertificate {
  [CmdletBinding()]
  param (
    [string]$SubjectName,
    [string]$FriendlyName = "New Certificate",
    [object]$Issuer,
    [bool]$IsCA = $false,
    [int]$KeyStrength = 2048,
    [int]$ValidYears = 2,
    [hashtable]$EKU = @{}
  )

  # Needed generators
  $random = New-SecureRandom
  $certificateGenerator = New-CertificateGenerator

  if($Issuer -ne $null -and $Issuer.HasPrivateKey -eq $true)
  {
    $IssuerName = $Issuer.IssuerName.Name
    $IssuerPrivateKey = $Issuer.PrivateKey
  }
  # Create and set a random certificate serial number
  $serial = New-SerialNumber -Random $random
  $certificateGenerator.SetSerialNumber($serial)

  # The signature algorithm
  $certificateGenerator.SetSignatureAlgorithm('SHA256WithRSA')

  # Basic Constraints - certificate is allowed to be used as intermediate.
  # Powershell requires either a $null or reassignment or it will return this from the function
  $certificateGenerator = Add-BasicConstraints -isCertificateAuthority $IsCA -certificateGenerator $certificateGenerator

  # Key Usage
  if($EKU.Count -gt 0) 
  {
    $certificateGenerator = $certificateGenerator | Add-ExtendedKeyUsage @EKU
  }
  # Create and set the Issuer and Subject name
  $subjectDN = New-X509Name -Name ($SubjectName)
  if($Issuer -ne $null) {
    $IssuerDN = New-X509Name -Name ($IssuerName)
  }
  else 
  {
    $IssuerDN = New-X509Name -Name ($SubjectName)
  }  
  $certificateGenerator.SetSubjectDN($subjectDN)
  $certificateGenerator.SetIssuerDN($IssuerDN)

  # Authority Key and Subject Identifier
  if($Issuer -ne $null)
  {
    $IssuerKeyPair = ConvertTo-BouncyCastleKeyPair -PrivateKey $IssuerPrivateKey
    $IssuerSerial = [Org.BouncyCastle.Math.BigInteger]$Issuer.GetSerialNumber()
    $authorityKeyIdentifier = New-AuthorityKeyIdentifier -name $Issuer.IssuerName.Name -publicKey $IssuerKeyPair.Public -serialNumber $IssuerSerial
    $certificateGenerator = Add-AuthorityKeyIdentifier -certificateGenerator $certificateGenerator -authorityKeyIdentifier $authorityKeyIdentifier
  }

  # Validity range of the certificate
  [DateTime]$notBefore = (Get-Date).AddDays(-1)
  if($ValidYears -gt 0) {
    [DateTime]$notAfter = $notBefore.AddYears($ValidYears)
  }
  $certificateGenerator.SetNotBefore($notBefore)
  $certificateGenerator.SetNotAfter($notAfter)


  # Subject public key ~and private
  $subjectKeyPair = New-KeyPair -Strength $keyStrength -Random $random
  if($IssuerPrivateKey -ne $null)
  {
    $IssuerKeyPair = [Org.BouncyCastle.Security.DotNetUtilities]::GetKeyPair($IssuerPrivateKey)
  }
  else 
  {
    $IssuerKeyPair = $subjectKeyPair
  }
  $certificateGenerator.SetPublicKey($subjectKeyPair.Public)

  # Create the Certificate
  $IssuerKeyPair = $subjectKeyPair
  $certificate = $certificateGenerator.Generate($IssuerKeyPair.Private, $random)
  # At this point you have the certificate and need to convert it and export, I return the private key for signing the next cert
  $pfxCertificate = ConvertFrom-BouncyCastleCertificate -certificate $certificate -subjectKeyPair $subjectKeyPair -friendlyName $FriendlyName
  return $pfxCertificate
}

Voici quelques exemples d'utilisation de ce PowerShell:

Génère une autorité de certification racine

$TestRootCA = New-SelfSignedCertificate -subjectName "CN=TestRootCA" -IsCA $true
Export-Certificate -Certificate $test -OutputFile "TestRootCA.pfx" -X509ContentType Pfx

Génère un standard auto-signé

$TestSS = New-SelfSignedCertificate -subjectName "CN=TestLocal"
Export-Certificate -Certificate $TestSS -OutputFile "TestLocal.pfx" -X509ContentType Pfx

Génère un certificat, en signant avec un certificat racine

$TestRootCA = New-SelfSignedCertificate -subjectName "CN=TestRootCA" -IsCA $true
$TestSigned = New-SelfSignedCertificate -subjectName "CN=TestSignedByRoot" -issuer $TestRootCA

Export-Certificate -Certificate $test -OutputFile "TestRootCA.pfx" -X509ContentType Pfx
Export-Certificate -Certificate $test -OutputFile "TestRootCA.pfx" -X509ContentType Pfx

Génère un auto-signé avec une utilisation spécifique

$TestServerCert = New-SelfSignedCertificate -subjectName "CN=TestServerCert" -EKU @{ "ServerAuthentication" = $true }

Notez que le paramètre -EKU accepte via splatting, il s'assure que tout ce qui est ajouté à Add-ExtendedKeyUsage est valablement passé. Il accepte les utilisations de certificat suivantes:

  • Signature numérique
  • Non répudiation
  • KeyEncipherment
  • DataEncipherment
  • KeyAgreement
  • KeyCertSign
  • CrlSign
  • Chiffré seulement
  • Déchiffrer seulement

Cela répond à mes besoins et semble fonctionner sur toutes les plates-formes Windows que nous utilisons pour les environnements dynamiques.

8
LimpingNinja

"Générateur de certificats Itiverba Self-Signed" ( http://www.itiverba.com/fr/software/itisscg.php ) est un outil graphique gratuit pour Windows qui vous permet de créer vos propres certificats d'autorité de certification et de signer -certifie avec elle. Vous pouvez exporter les certificats aux formats de fichier PEM, CER, DER, PFX.

Il n’ya que 3 lignes pour encoder:
Subject: CN = "Testcorp - Private CA"
Contraintes de base: V (vérifié)
Contraintes de base/Type de sujet: CA

Donnez un nom de fichier et sélectionnez un format de fichier, puis cliquez sur le bouton "Créer un certificat". Votre certificat CA personnalisé est terminé.

3
Steph

Pourquoi ne pas simplement faire ceci:

$cert = New-SelfSignedCertificate -FriendlyName "MyCA"
      -KeyExportPolicy ExportableEncrypted 
      -Provider "Microsoft Strong Cryptographic Provider" 
      -Subject "SN=TestRootCA" -NotAfter (Get-Date).AddYears($ExpiryInYears) 
      -CertStoreLocation Cert:\LocalMachine\My -KeyUsageProperty All 
      -KeyUsage CertSign, CRLSign, DigitalSignature

Les paramètres importants sont -KeyUsageProperty et -KeyUsage.

0
Adriaan de Beer