简体   繁体   English

通过 PowerShell 创建 PEM 文件

[英]Creating PEM file through PowerShell

I am trying to code a script to create a PEM certificate file in powershell.我正在尝试编写脚本以在 powershell 中创建 PEM 证书文件。 I am not sure if what I did is totally wrong, but when I tried to use the PEM file in and socat OPENSSL it returned the error:我不确定我所做的是否完全错误,但是当我尝试在和 socat OPENSSL 中使用 PEM 文件时,它返回了错误:

$ socat OPENSSL-LISTEN:1337,cert=cert.pem,verify=0 -

socat[1209] E SSL_CTX_use_certificate_file(): error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag
#create certificate
$cert = New-SelfSignedCertificate `
    -Subject "MYHOSTNAME" `
    -TextExtension @("2.5.29.17={text}DNS=MYHOSTNAME&IPAddress=192.168.1.100") `
    -KeySpec Signature `
    -HashAlgorithm SHA256 `
    -KeyExportPolicy Exportable

#publicKey
$PublicKey = $cert.GetPublicKey();
$PublicKeyB64 = [Convert]::ToBase64String($PublicKey,"InsertLineBreaks");

#privateKey
$RSACng  = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert);
$PrivateKey = $RSACng.Key;
$PrivateKeyByte = $PrivateKey.Export("PRIVATEBLOB");
$PrivateKeyB64 = [Convert]::ToBase64String($PrivateKeyByte,"InsertLineBreaks");

#createFile
$out = New-Object string[] -ArgumentList 6;
$out[0] = "-----BEGIN PRIVATE KEY-----";
$out[1] = $PrivateKeyB64;
$out[2] = "-----END PRIVATE KEY-----"

$out[3] = "-----BEGIN CERTIFICATE-----"
$out[4] = $publicKeyB64;
$out[5] = "-----END CERTIFICATE-----"

[IO.File]::WriteAllLines("C:\Users\Public\cert.pem",$out)

I am not sure if what I did is totally wrong, but I could not find any resource to help me proceed.我不确定我所做的是否完全错误,但我找不到任何资源来帮助我继续。

Some script that perform similar action of creating a PEM file in powershell or some tip about how to proceed could be value to help me fix this one.一些执行在 powershell 中创建 PEM 文件的类似操作的脚本或有关如何继续的一些提示可能对帮助我解决这个问题很有价值。

You can also use CertUtil.exe.您也可以使用 CertUtil.exe。 Go through this once Go 通过此一次

Certutil.exe is a command-line program, installed as part of Certificate Services. Certutil.exe 是一个命令行程序,作为证书服务的一部分安装。

So simple script for creating.PEM with powershell is as follows:使用 powershell 创建.PEM 的简单脚本如下:

 $certpwd = '***'
$certpwd1 = ConvertTo-SecureString -String $certpwd -Force –AsPlainText
$certpwd2 = 'pass:' + $certpwd
$certname = $env:COMPUTERNAME
del c:\temp\$certname.*

$cert = New-SelfSignedCertificate -DnsName $certname -certStorelocation cert:\localmachine\my -KeyLength 2048  -KeyFriendlyName $certname -FriendlyName $friendlyName -HashAlgorithm sha256 -keyexportpolicy exportableencrypted -keyspec KeyExchange -NotAfter (Get-Date).AddYears(2) | Out-Null

$cert2=Get-ChildItem Cert:\LocalMachine\my |
Where-Object { $_.FriendlyName -match $friendlyName }


$path = ‘cert:\localMachine\my\’ + $cert2.thumbprint
Export-Certificate -cert $path -FilePath c:\temp\$certname.der -type CERT –noclobber | Out-Null
certutil -encode c:\temp\$certname.der c:\temp\$certname.pem | Out-Null

What the script does is脚本的作用是

1)First it creates self signed certificate 1)首先它创建自签名证书

2)Then Export it to some physical path in form of.der 2)然后以.der的形式将其导出到某个物理路径

3)Use Certutil for encoding and thus creatig.pem file(.pem will be saved in c:\temp\ in this example) 3)使用 Certutil 进行编码,从而创建 creatig.pem 文件(在本例中,.pem 将保存在 c:\temp\ 中)

As commented, the data you are putting in the body of both PEM files is wrong.正如所评论的,您放入两个 PEM 文件正文中的数据是错误的。

For the certificate, it's easy, just use $cert.RawData (converted to base64 with linebreaks, as you already have).对于证书,这很容易,只需使用$cert.RawData (转换为 base64 并带有换行符,正如您已经拥有的那样)。

For the privatekey, according to the doc the RSA abstract returned by GetRSAPrivateKey($cert) ( not .Key ) and thus its implementations like RSACng have methods ExportPkcs8PrivateKey() which should be the correct data to put in a PEM file of type BEGIN/END PRIVATE KEY and also ExportRSAPrivateKey() which should be the older format that is correct for a PEM file of type BEGIN/END RSA PRIVATE KEY -- but only in Core 3.0+ and Five which I don't have and thus can't test.对于私钥,根据文档GetRSAPrivateKey($cert)而不是.Key )返回的RSA抽象,因此它的实现(如RSACng )具有方法ExportPkcs8PrivateKey() ,这应该是放入BEGIN/END PRIVATE KEY类型的 PEM 文件中的正确数据BEGIN/END PRIVATE KEYExportRSAPrivateKey()这应该是旧格式,对于BEGIN/END RSA PRIVATE KEY类型的 PEM 文件是正确的——但仅限于 Core 3.0+ 和我没有的五个,因此不能测试。

A workaround if you have openssl commandline is to Export-PfxCertificate to a file, which openssl pkcs12 [-nodes] can then convert to the PEM formats OpenSSL (and thus socat ) likes.如果您有openssl命令行,解决方法是将 PfxCertificate Export-PfxCertificate到文件,然后openssl pkcs12 [-nodes] socat转换为 PEM 格式 ZEE302FD5FD2A7A579A3C19FC5BE21 (F. But if you have openssl commandline you can easily use it to generate the privatekey and (selfsigned/dummy) cert directly, without futzing with powershell.但是,如果您有openssl命令行,您可以轻松地使用它直接生成私钥和(自签名/虚拟)证书,而无需使用 powershell。

I had trouble with both previous answers.我对以前的两个答案都有问题。 After much searching and testing, I found a method that works with vanilla powershell and few (no?) permissions.经过大量搜索和测试,我找到了一种适用于 vanilla powershell 并且很少(没有?)权限的方法。

This script also gives the self signed cert as a pfx, der, and pem file.此脚本还将自签名证书作为 pfx、der 和 pem 文件提供。

$dir = "c:\temp\"

$subj = "CN=YOUR_SUBJECT" #need either DnsName or Subject when calling New-SelfSignedCertificate

$friendlyName = "YOUR_FRIENDLY_NAME"

$pfxFilePath = $dir, $friendlyName, ".pfx" -join ""

$derFilePath = $dir, $friendlyName, ".der" -join ""

$pemFilePath = $dir, $friendlyName, ".pem" -join ""

#create new certificate in cert:\currentuser\my and store in variable $cert
$cert = New-SelfSignedCertificate -CertStoreLocation cert:\currentuser\my -Subject $subj -KeyAlgorithm RSA -KeyLength 2048 -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -KeyExportPolicy Exportable -FriendlyName $friendlyName -NotAfter (Get-Date).AddYears(2)

#get password for pfx file
$pw = Read-Host "Enter Password:"

#export cert to pfx and write to file 
[io.file]::WriteAllBytes($pfxFilePath,$cert.Export(3, $pw))

#export cert to der and write to file
Export-Certificate -FilePath $derFilePath -Cert $cert

#encode der file as pem file and write to file
certutil -encode $derFilePath $pemFilePath | Out-Null

You are close, this is how it will work:你很接近,这就是它的工作方式:

# Public key to Base64
$PubBase64 = [System.Convert]::ToBase64String($cert.RawData, [System.Base64FormattingOptions]::InsertLineBreaks)

# Private key to Base64
$RSACng = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
$PrivBytes = $RSACng.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)
$PrivBase64 = [System.Convert]::ToBase64String($PrivBytes, [System.Base64FormattingOptions]::InsertLineBreaks)

# Put it all together
$Pem = @"
-----BEGIN PRIVATE KEY-----
$PrivBase64
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
$PubBase64
-----END CERTIFICATE-----
"@

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM