Files
powershell-scripts/winrm-https/TROUBLESHOOTING_CERTIFICATE_GENERATION.md
cproudlock 96cb1dd946 Remove all emojis from markdown documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 11:03:45 -05:00

426 lines
10 KiB
Markdown

# Troubleshooting Certificate Generation Issues
## Common Error: "Smart card select a smart card device the security device is read-only"
This error occurs when using `New-SelfSignedCertificate` on systems with:
- Smart card policies enforced by Group Policy
- Smart card readers attached
- Restricted certificate store permissions
- TPM (Trusted Platform Module) restrictions
### Quick Fixes
#### Fix 1: Use Alternative Certificate Generation Script
```powershell
# Use the alternative script that bypasses smart card issues
.\Generate-WildcardCert-Alternative.ps1
```
This script uses `certreq.exe` instead of `New-SelfSignedCertificate` to avoid smart card device errors.
---
#### Fix 2: Temporarily Disable Smart Card Service
```powershell
# Stop smart card service temporarily
Stop-Service -Name "SCardSvr" -Force
# Run certificate generation
.\Generate-WildcardCert.ps1
# Restart service
Start-Service -Name "SCardSvr"
```
**Note:** Requires Administrator privileges. May affect other applications using smart cards.
---
#### Fix 3: Use Different Crypto Provider
```powershell
# Generate certificate with specific provider
$cert = New-SelfSignedCertificate `
-DnsName "*.logon.ds.ge.com", "logon.ds.ge.com" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
-KeyExportPolicy Exportable `
-KeySpec KeyExchange `
-NotAfter (Get-Date).AddYears(2)
```
---
#### Fix 4: Generate Certificate via CertReq
**Step 1: Create request file**
Create `cert-request.inf`:
```ini
[Version]
Signature="$Windows NT$"
[NewRequest]
Subject="CN=*.logon.ds.ge.com"
KeyLength=2048
KeyAlgorithm=RSA
HashAlgorithm=SHA256
MachineKeySet=TRUE
Exportable=TRUE
RequestType=Cert
KeyUsage=0xA0
KeyUsageProperty=0x02
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=*.logon.ds.ge.com&"
_continue_ = "dns=logon.ds.ge.com&"
2.5.29.37 = "{text}"
_continue_ = "1.3.6.1.5.5.7.3.1,"
[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.1
```
**Step 2: Generate certificate**
```powershell
# Create certificate using certreq
certreq.exe -new -f cert-request.inf wildcard.cer
# Find the certificate
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*logon.ds.ge.com*" } |
Sort-Object NotBefore -Descending |
Select-Object -First 1
# Export to PFX
$password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force
Export-PfxCertificate -Cert $cert `
-FilePath "wildcard-logon-ds-ge-com.pfx" `
-Password $password
```
---
#### Fix 5: Generate on Different Computer
If the above methods don't work, generate the certificate on a computer without smart card restrictions:
1. **Generate on unrestricted computer:**
```powershell
.\Generate-WildcardCert.ps1
```
2. **Copy PFX file to restricted computer:**
```powershell
Copy-Item "wildcard-*.pfx" -Destination "\\RestrictedComputer\C$\Temp\"
```
3. **Use on restricted computer:**
```powershell
.\Setup-WinRM-HTTPS.ps1 -CertificatePath "C:\Temp\wildcard-*.pfx" `
-Domain "logon.ds.ge.com"
```
---
## Other Common Certificate Errors
### Error: "Access Denied" When Creating Certificate
**Cause:** Insufficient permissions on certificate store
**Solution:**
```powershell
# Run PowerShell as Administrator
# Right-click PowerShell Run as Administrator
# Verify admin rights
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Error "This script requires Administrator privileges"
exit 1
}
```
---
### Error: "The parameter is incorrect" When Exporting
**Cause:** Password not in correct format
**Solution:**
```powershell
# Ensure password is SecureString
$password = Read-Host "Enter password" -AsSecureString
# NOT this (unless using -AsPlainText -Force)
# $password = "MyPassword" # Wrong type
```
---
### Error: "Cannot export non-exportable private key"
**Cause:** Certificate created without exportable flag
**Solution:**
```powershell
# When creating, ensure KeyExportPolicy is Exportable
$cert = New-SelfSignedCertificate `
-DnsName "*.logon.ds.ge.com" `
-KeyExportPolicy Exportable ` # Important!
-CertStoreLocation "Cert:\LocalMachine\My"
```
If already created, you must recreate the certificate.
---
### Error: "The trust chain could not be established"
**Cause:** Self-signed certificate not in Trusted Root store
**Solution:**
```powershell
# Import to Trusted Root
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*logon.ds.ge.com*" }
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
"Root", "LocalMachine"
)
$rootStore.Open("ReadWrite")
$rootStore.Add($cert)
$rootStore.Close()
Write-Host "Certificate added to Trusted Root"
```
---
## Group Policy Restrictions
### Check if Group Policy Restricts Certificates
```powershell
# Check certificate template policies
gpresult /H gpreport.html
# Open gpreport.html and search for "Certificate"
# Check smart card policies
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\SmartCardCredentialProvider"
```
### Workarounds for Group Policy
1. **Request exception from IT security team**
- Explain need for WinRM HTTPS testing
- Request temporary policy exemption
2. **Use test environment without policies**
- VM or workstation not in domain
- Generate certificates there
3. **Get certificate from Certificate Authority**
- Request wildcard cert from internal CA
- Avoids self-signed certificate issues
---
## Alternative: Use Existing Certificate
If you cannot generate certificates, use an existing one:
### Option 1: Use Existing Machine Certificate
```powershell
# Find existing exportable certificates
Get-ChildItem Cert:\LocalMachine\My |
Where-Object {
$_.HasPrivateKey -and
$_.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Key Usage" }
} |
Select-Object Subject, Thumbprint, NotAfter
# Use existing certificate by thumbprint
.\Setup-WinRM-HTTPS.ps1 -CertificateThumbprint "ABC123..." `
-Domain "logon.ds.ge.com"
```
### Option 2: Import Existing PFX
```powershell
# If you have a PFX file from elsewhere
$password = Read-Host "Enter PFX password" -AsSecureString
Import-PfxCertificate -FilePath "existing-cert.pfx" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-Password $password `
-Exportable
# Use it
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*your-domain*" }
.\Setup-WinRM-HTTPS.ps1 -CertificateThumbprint $cert.Thumbprint `
-Domain "logon.ds.ge.com"
```
---
## Using OpenSSL (Advanced)
If PowerShell methods fail completely, use OpenSSL:
### Install OpenSSL
```powershell
# Install via Chocolatey
choco install openssl -y
# Or download from: https://slproweb.com/products/Win32OpenSSL.html
```
### Generate Certificate with OpenSSL
```bash
# Generate private key
openssl genrsa -out wildcard.key 2048
# Generate certificate signing request
openssl req -new -key wildcard.key -out wildcard.csr -subj "/CN=*.logon.ds.ge.com"
# Create config file for SAN
cat > openssl.cnf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.logon.ds.ge.com
DNS.2 = logon.ds.ge.com
EOF
# Generate self-signed certificate
openssl x509 -req -days 730 -in wildcard.csr -signkey wildcard.key \
-out wildcard.crt -extensions v3_req -extfile openssl.cnf
# Create PFX
openssl pkcs12 -export -out wildcard.pfx \
-inkey wildcard.key -in wildcard.crt \
-passout pass:YourPassword
```
### Import OpenSSL Certificate
```powershell
# Import the PFX created by OpenSSL
$password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force
Import-PfxCertificate -FilePath "wildcard.pfx" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-Password $password `
-Exportable
```
---
## Verification Steps
After generating certificate by any method:
```powershell
# 1. Verify certificate exists
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*logon.ds.ge.com*" }
if ($cert) {
Write-Host "Certificate found!" -ForegroundColor Green
Write-Host "Subject: $($cert.Subject)"
Write-Host "Thumbprint: $($cert.Thumbprint)"
Write-Host "Has Private Key: $($cert.HasPrivateKey)"
Write-Host "Expires: $($cert.NotAfter)"
} else {
Write-Host "Certificate not found!" -ForegroundColor Red
}
# 2. Verify exportable
if ($cert.PrivateKey.CspKeyContainerInfo.Exportable) {
Write-Host "Private key is exportable" -ForegroundColor Green
} else {
Write-Host "Private key is NOT exportable" -ForegroundColor Red
}
# 3. Test export
try {
$testPassword = ConvertTo-SecureString "test" -AsPlainText -Force
$testPath = "$env:TEMP\test-export.pfx"
Export-PfxCertificate -Cert $cert -FilePath $testPath -Password $testPassword
Remove-Item $testPath -Force
Write-Host "Export test successful" -ForegroundColor Green
} catch {
Write-Host "Export test failed: $($_.Exception.Message)" -ForegroundColor Red
}
```
---
## Getting Help
If none of these solutions work:
1. **Check Event Viewer:**
```powershell
# View certificate-related errors
Get-EventLog -LogName Application -Source "Microsoft-Windows-CertificateServicesClient-CertEnroll" -Newest 10
```
2. **Enable certificate logging:**
```powershell
# Enable detailed certificate logging
wevtutil sl Microsoft-Windows-CertificateServicesClient-Lifecycle-System /e:true
wevtutil sl Microsoft-Windows-CertificateServicesClient-Lifecycle-User /e:true
```
3. **Check Group Policy settings:**
```powershell
gpresult /H C:\Temp\gpreport.html
# Open and search for certificate or smart card policies
```
4. **Test with makecert (legacy):**
```powershell
# If available (older Windows SDK)
makecert -r -pe -n "CN=*.logon.ds.ge.com" -sky exchange -ss my
```
5. **Contact IT/Security team:**
- Request certificate from internal CA
- Request policy exemption
- Request assistance with certificate generation
---
## Summary
**Recommended approach when you see smart card error:**
1. Try `Generate-WildcardCert-Alternative.ps1` (uses certreq)
2. Try disabling smart card service temporarily
3. Try different crypto provider
4. Generate on different computer without restrictions
5. Request certificate from your organization's CA
**For production deployment:**
- Always get certificates from trusted Certificate Authority
- Self-signed certificates are for testing only
- Document any workarounds used