15

I'm trying to create a self signed certificate with specific encryption parameter values.

On a Win Server 2012 r2 standard running PowerShell 5.0, when I attempt to use

New-SelfSignedCertificate

I receive an error:

New-SelfSignedCertificate : A parameter cannot be found that matches parameter name 'Subject'.

when I attempt to use the -Subject parameter, which in addition to other parameters allowed on my laptop, does not appear in the intellisense.

However on my laptop (Win 10 and PowerShell 5.0) I'm allowed to use these parameters, and I create a self-signed certificate by using the following code

#create a Certificate
# OID for document encryption
    $Oid = New-Object System.Security.Cryptography.Oid "1.3.6.1.4.1.311.80.1"
    $oidCollection = New-Object System.Security.Cryptography.OidCollection
    $oidCollection.Add($oid) > $Null
# Create enhanced key usage extension that allows document encryption
$Ext = New-Object System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension $oidCollection, $true 

$myCert = New-SelfSignedCertificate -Subject 'CN=myservernameasubject' -CertStoreLocation "Cert:\LocalMachine\My" -KeySpec KeyExchange -KeyUsage KeyEncipherment, DataEncipherment -Extension $Ext
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Samer
  • 3,848
  • 4
  • 25
  • 24

2 Answers2

18

Use -DnsName instead without the CN=.

From the PowerShell help:

-DnsName <String> Specifies one or more DNS names to put into the Subject Alternative Name extension of the certificate when a certificate to be copied is not specified via the CloneCert parameter. The first DNS name is also saved as Subject Name and Issuer Name.

The -KeySpec and other related options are, unfortunately, not supported by New-SelfSignedCertificate in Windows Server 2012 R2 and Windows 8.1. Otherwise, you're looking at one of three options to generate the desired certificate; Adapt the COM object based code in the answer to How to create a self-signed certificate using C#? to use in PowerShell, use an external executable like makecert.exe, or generate the certificate/key pair elsewhere and then import it to the certificate store on the other machine.

Update: After further research, it looks like adapting COM based code in PowerShell is a good option. I found a blog entry by Vishal Agarwal, Generating a certificate (self-signed) using powershell and CertEnroll interfaces, that gives the following PowerShell code:

$name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
$name.Encode("CN=TestServer", 0)

$key = new-object -com "X509Enrollment.CX509PrivateKey.1"
$key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
$key.KeySpec = 1
$key.Length = 1024
$key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
$key.MachineContext = 1
$key.Create()

$serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
$serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")
$ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
$ekuoids.add($serverauthoid)
$ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
$ekuext.InitializeEncode($ekuoids)

$cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
$cert.InitializeFromPrivateKey(2, $key, "")
$cert.Subject = $name
$cert.Issuer = $cert.Subject
$cert.NotBefore = get-date
$cert.NotAfter = $cert.NotBefore.AddDays(90)
$cert.X509Extensions.Add($ekuext)
$cert.Encode()

$enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
$enrollment.InitializeFromRequest($cert)
$certdata = $enrollment.CreateRequest(0)
$enrollment.InstallResponse(2, $certdata, 0, "")
Community
  • 1
  • 1
JamieSee
  • 12,696
  • 2
  • 31
  • 47
  • I apologize because my question does sound misleading. My problem is that I need a way to input encryption values so that the certificate will have a private key. I understand that DnsName is the alternative but it doesn't cover the encryption parameters. – Samer Mar 10 '16 at 19:14
  • So if you use the same command with DnsName instead of Subject does it end up just finding a different parameter to complain about? – JamieSee Mar 10 '16 at 19:23
  • Yes! As I mentioned in the question, the intellisense doesn't show the full list of parameters, and it complains when I attempt to type any of the missing parameters, which I get to use in my powershell environment on my laptop. – Samer Mar 10 '16 at 21:35
  • @SamersSalib Update after some further research. I think this may get you where you need to go. – JamieSee Mar 10 '16 at 23:15
  • It worked! Thank you @JamieSee. I'm still wondering why my 2012 r2 servers (Now two of them) are missing the parameters associated with specifying the encryption keys and info. It sounds like the powershell environment of the servers, is not the same as windows 10 ps environment. – Samer Mar 10 '16 at 23:27
  • That's correct. There were enhancements added in Windows 10 that have not made it to the Server OS and might not until the next version of Server is released. Since this did the trick would you please mark it as an accepted answer? – JamieSee Mar 10 '16 at 23:33
  • 1
    Ah! Had to go to FAQ to learn how to accept an answer. Thank you again. – Samer Mar 11 '16 at 00:08
  • Maybe this tool could help you a lot. https://gallery.technet.microsoft.com/scriptcenter/Self-signed-certificate-5920a7c6 – Kirin Yao Oct 24 '17 at 10:41
1

The following worked just fine for the self-signed option...

New-SelfSignedCertificate -DnsName "*.costoso100.com" -CertStoreLocation "cert:\LocalMachine\My"

I was able to export and setup LDAPS in about 15 minutes.

CLBdS
  • 27
  • 1