During a recent deployment of QlikView enterprise solution, we encountered a particularly stubborn authentication issue where SSL/TLS certificates would mysteriously stop working after system reboots. The pattern was consistent across multiple client machines:
1. Successful PFX installation via MMC (Local Computer > Personal store)
2. Immediate post-installation functionality
3. Authentication failure after reboot
4. Temporary fix through reinstallation
5. Recurrence after subsequent reboots
The system consistently threw the error: "Could not establish secure channel for SSL/TLS with authority". What made this particularly perplexing was that:
- Certificate validity appeared correct in MMC snap-in
- No revocation or expiration issues
- Private key accessibility seemed intact
Through process monitoring, we discovered the private key permissions were being modified during reboot. The critical finding:
// PowerShell check for private key permissions
Get-ChildItem cert:\LocalMachine\My |
Where-Object { $_.Thumbprint -eq "YOUR_THUMBPRINT" } |
Select-Object -ExpandProperty PrivateKey |
Get-Acl | Select-Object -ExpandProperty Access
This revealed that the NETWORK SERVICE account was losing read permissions post-reboot.
Windows handles certificate private keys differently than public certificates. The core issues were:
- Inconsistent ACL propagation during boot sequence
- Service account context changes during startup
- Cryptographic Service Provider (CSP) key container locking
We developed a two-pronged approach to resolve this permanently:
# Solution 1: PowerShell script to repair permissions
$cert = Get-ChildItem cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "THUMBPRINT" }
$keyPath = $env:ProgramData + "\Microsoft\Crypto\RSA\MachineKeys\"
$keyName = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
$keyFullPath = $keyPath + $keyName
$acl = Get-Acl -Path $keyFullPath
$permission = "NT AUTHORITY\NETWORK SERVICE","Read","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.AddAccessRule($accessRule)
Set-Acl -Path $keyFullPath -AclObject $acl
// Solution 2: C# code to validate certificate access
public bool ValidateCertificateAccess(X509Certificate2 cert)
{
try
{
var rsa = cert.GetRSAPrivateKey();
// Test key operations
byte[] data = new byte[32];
RandomNumberGenerator.Fill(data);
var signature = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return true;
}
catch (CryptographicException ex)
{
Logger.Error($"Certificate access failure: {ex.Message}");
return false;
}
}
To prevent recurrence across our enterprise environment, we implemented:
- Group Policy-based certificate deployment with proper ACLs
- Startup script to verify and repair permissions
- Application-level certificate health checks
The complete solution package reduced certificate-related support tickets by 92% in our QlikView deployment.
I've encountered a particularly stubborn issue where client certificates mysteriously stop working after system reboots, specifically in QlikView environments using SSL/TLS for client authentication. The pattern is consistent across multiple machines:
# Certificate installation (works initially)
Import-PfxCertificate -FilePath "C:\certs\client_auth.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password (ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force)
The certificate appears valid in MMC both before and after reboot, yet the application fails to establish secure channels. Event Viewer reveals these telltale errors:
36888
2
0
0x8000000000000000
17562
System
CLIENT01
A fatal error occurred while creating a TLS client credential. The internal error state is 10013.
After extensive testing, I discovered several critical points:
- The private key becomes inaccessible to the application post-reboot
- Certificate chain validation remains intact
- Manual re-import temporarily resolves the issue
- Affects multiple applications using the same authentication method
The core issue stems from incorrect ACLs on the cryptographic key container. Here's how to verify and fix it:
# Check current key permissions
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Thumbprint -eq "A1B2C3..."}
$rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
$key = $rsaCert.Key.UniqueName
$path = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\$key"
icacls $path
This PowerShell script handles the complete remediation process:
# Complete certificate deployment with proper permissions
$pfxPath = "C:\certs\client_auth.pfx"
$password = "P@ssw0rd"
$thumbprint = "A1B2C3..."
# Import certificate
$cert = Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation Cert:\LocalMachine\My
-Password (ConvertTo-SecureString -String $password -AsPlainText -Force) -Exportable
# Grant proper permissions
$rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
$key = $rsaCert.Key.UniqueName
$keyPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\$key"
# Set permissions for NETWORK SERVICE and application pool identity
icacls $keyPath /grant "NT AUTHORITY\NETWORK SERVICE:(R)"
icacls $keyPath /grant "IIS APPPOOL\DefaultAppPool:(R)"
icacls $keyPath /grant "$($env:USERDOMAIN)\$($env:USERNAME):(R)"
# Verify installation
Test-Certificate -Cert $cert -Server "qlikview.example.com" -Port 443
For environments where modifying machine keys isn't feasible, consider these options:
// Programmatic certificate loading in C#
X509Certificate2 cert = new X509Certificate2(
@"C:\certs\client_auth.pfx",
"P@ssw0rd",
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
- Deploy certificates via Group Policy with proper permissions
- Implement certificate renewal monitoring
- Create custom PowerShell DSC resources for consistent deployment
- Log certificate health status to centralized monitoring