bestsource

윈도우즈에서 OpenSSL을 사용하지 않고 pfx 파일 또는 인증서 저장소에서 개인 키 추출

bestsource 2023. 9. 1. 21:12
반응형

윈도우즈에서 OpenSSL을 사용하지 않고 pfx 파일 또는 인증서 저장소에서 개인 키 추출

제목에서 알 수 있듯이 OpenSSL이나 다른 타사 도구를 사용하지 않고 개인 키를 내보내고 싶습니다.필요한 경우.cer파일 또는.pfxMMC 또는 PowerShell을 통해 파일을 쉽게 내보낼 수 있습니다.pkiclient개인 키를 가져올 방법을 찾을 수가 없어요

https://learn.microsoft.com/en-us/powershell/module/pkiclient/export-certificate?view=win10-ps

https://www.sslshopper.com/ssl-converter.html 과 같은 온라인 도구를 사용하는 것은 좋지 않습니다.

PS 버전:

PS C:\Users\oscar> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17134.228
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17134.228
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

다음과 같이 공용 키를 가져올 수 있습니다.

(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()

그리고 다음과 같이 전체 인증서를 내보냅니다.

(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()

으로부터 결과가 나온

PS C:\Users\oscar> $mypwd = ConvertTo-SecureString -String "MyPassword" -Force -AsPlainText
PS C:\Users\oscar> $mypfx = Get-PfxData -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $mypwd
PS C:\Users\oscar> $mypfx

OtherCertificates EndEntityCertificates
----------------- ---------------------
{}                {[Subject]...


PS C:\Users\oscar> $mypfx.EndEntityCertificates

Thumbprint                                Subject
----------                                -------
8ED4971564E35099D6DB490C3756E2AD43AAAAAA  CN=localhost

@Brad에서 명령을 테스트했지만 아래 오류가 발생했습니다.

개인 키는 일반 텍스트를 내보낼 수 없습니다.

certutil -exportPFX -p "myPassword" -privatekey -user my <Certificate Serial Number> C:\localhost.pfx

enter image description here

MMC 인증서의 인증서 내보내기 마법사와 유사하게 다음으로 내보내기만 합니다..pfx키가 포함된 경우 사용할 수 있습니다.

enter image description here

저도 같은 문제가 있었는데 PS 갤러리의 PSPKI Powershell 모듈의 도움을 받아 해결했습니다.Windows에 내장된 일부 기능을 사용하는 솔루션을 찾는 것으로 알고 있지만 PS Gallery에서 모듈을 설치하는 것이 허용될 수도 있습니다.적어도 제 경우에는 그랬습니다.

먼저 PSPKI 모듈을 설치합니다(PSGallery 저장소가 이미 설정되어 있다고 가정합니다).

Install-Module -Name PSPKI

PSPKI 모듈은 Cmdlet을 제공합니다.Convert-PfxToPempfx 파일을 인증서 및 해적 키가 포함된 pem-file로 변환합니다. 여기에는 base64-timeout 텍스트가 포함됩니다.

Convert-PfxToPem -InputFile C:\path\to\pfx\file.pfx -Outputfile C:\path\to\pem\file.pem

이제 우리가 해야 할 일은 정규식 마법으로 펨 파일을 나누는 것뿐입니다.예를 들어, 다음과 같습니다.

(Get-Content C:\path\to\pem\file.pem -Raw) -match "(?ms)(\s*((?<privatekey>-----BEGIN PRIVATE KEY-----.*?-
----END PRIVATE KEY-----)|(?<certificate>-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----))\s*){2}"

$Matches["privatekey"] | Set-Content "C:\path\to\key\file.pem"
$Matches["certificate"] | Set-Content "C:\path\to\certificate\file.pem"

파노스를 찾았어요G의 대답은 꽤 유망했지만, 효과를 거두지 못했습니다.내 인증서 개체에서 설명된 세 가지 메서드를 모두 사용할 수 없습니다.좀 더 깊이 연구한 후에, 저는 다음과 같은 해결책을 생각해냈습니다.

참고: 인증서 저장소에서 인증서를 읽으면 작동합니다.만약 당신이 읽는다면, 그것은 작동하지 않습니다..pfx로 철하다.Get-PfxCertificate,예를들면.파일로 저장하기만 하면 인증서 저장소에 설치하여 다음과 같이 해당 저장소에서 읽을 수 있습니다.

# Read the certificate from the certificate store
# In this example, I use the certificate thumbprint to identify the certificate.
$cert = Get-ChildItem Cert:\ -Recurse | ? {$_.Thumbprint -eq '<THUMBPRINT_OF_CERTIFICATE>'}

# Read the private key into an RSA CNG object:
$RSACng = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)

# Get the bytes of the private key
$KeyBytes = $RSACng.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)

# Encode the bytes (Base64)
$KeyBase64 = [System.Convert]::ToBase64String($KeyBytes, [System.Base64FormattingOptions]::InsertLineBreaks)

# Put it all together
$KeyPem = @"
-----BEGIN PRIVATE KEY-----
$KeyBase64
-----END PRIVATE KEY-----
"@

문서:

스택 프로텍터의 기존 답변을 기반으로 .pfx 파일에서 직접 읽을 때 작동하는 fragment를 추가하고 싶습니다.

파일에서 읽을 때 PowerShell Get-PfxCertificate를 사용하는 대신 X509StorageFlag Exportable을 지정할 수 있는 .net core의 메서드를 사용해야 합니다.

# Password is a plain string, not a securestring
$cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2( 
      $filename, 
      $password, 
      [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)

# now continue as with the other solutions
# Read the private key into an RSA CNG object:
$RSACng = [Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)

# Get the bytes of the private key
$KeyBytes = $RSACng.Key.Export([Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)

# Encode the bytes (Base64)
$KeyBase64 = [Convert]::ToBase64String($KeyBytes, [Base64FormattingOptions]::InsertLineBreaks)

# Put it all together
$KeyPem = @"
-----BEGIN PRIVATE KEY-----
$KeyBase64
-----END PRIVATE KEY-----
"@

PowerShellGuy가 언급한 내용을 기반으로 합니다.

그것이 당신에게 효과가 있습니까?

# first get your cert, either via pure .NET, or through the PSDrive (Cert:\)

# this is just an example

# get cert from PSDrive
$cert = Get-ChildItem Cert:\LocalMachine\My | where Subject -eq 'CN=MySubject'

# get cert from .NET
$My     = [System.Security.Cryptography.X509Certificates.StoreName]::My
$Store  = [System.Security.Cryptography.X509Certificates.X509Store]::new($My,'localmachine')
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::MaxAllowed)

$cert   = $Store.Certificates | where Subject -eq 'CN=MySubject'

# get private key
# PKCS8, way #1
$BytesPkcs8 = $cert.PrivateKey.ExportPkcs8PrivateKey()
[System.Convert]::ToBase64String($BytesPkcs8)

# PKCS8, way #2
$Pkcs = [System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob
$BytesPkcs8 = $cert.PrivateKey.Key.Export($Pkcs)
[System.Convert]::ToBase64String($BytesPkcs8)

# RSA
$BytesRsa = $cert.PrivateKey.ExportRSAPrivateKey()
[System.Convert]::ToBase64String($BytesRsa)

그래서 당신이 찾고 있는 것이 그 Base64 문자열입니까?

흠. 당신은 인증서 가게를 열고, 개인 키를 그런 식으로 얻으려고 시도해 본 적이 있습니까?하지만 RSA/DSA 인증서에서만 작동할 것이라고 확신합니다.

$store = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::My,"localmachine")
$store.Open("MaxAllowed")
$cert = $store.Certificates | ?{$_.subject -match "^CN=asdasd"}
$cert.PrivateKey.ToXmlString($false)
$store.Close()

제가 제대로 이해했다면 확실히 해주셔야 합니다.

certutil -exportPFX -p "ThePasswordToKeyonPFXFile" my [serialNumberOfCert] [fileNameOfPFx]

언급URL : https://stackoverflow.com/questions/52929805/extract-private-key-from-pfx-file-or-certificate-store-without-using-openssl-on

반응형