Difference between revisions of "Private Key Component"

From MgmtWiki
Jump to: navigation, search
(Cryptography Next Generation (CNG))
(Cryptography Next Generation (CNG))
Line 57: Line 57:
* [https://gist.github.com/milesgratz/38804dfc336df64191f958004953e9b6 More complex script to Update-machine-certificate-private-key-permissions.ps1]

Revision as of 12:37, 26 July 2020

Full Title or Meme

Good Public Key Cryptography is dependent on the absolute protection of the Private Key Component of the public/private key pair.


  • The goal of a Private Key Component is give the user an Authentication factor that can be completely within their control.
  • Should some other technology for the use of secret data be found beyond the Private Key Component, it is expected that this wiki page should apply to that new technology as well.


  • Protecting one's secret information, in the modern age of computers, has become synonymous with protect a secret key or a Private Key Component of a key pair.
  • This wiki uses the term Credential for any secret held by a device that can be used in authenticating a user. The best known credential (2020) is a well-protected private key component.
  • Another technology that antedates Public Key technology is a shared secret, such as One-Time Password Authenticators (OTP). Those continue to be useful.


  • Governments have been the primary customers for keeping secrets and, so, the primary customers for cryptography.
  • The challenge with providing good secrecy became a challenge to (1) find a good cryptography algorithm and (2) getting the cryptographic key security into the hands of those who need it.


  • NIST SP 800-63-3B established authentication assurance level (AAL) the reports the protection level of the user's private key components.
  • Note that web URLs are case-insensitive which means that string comparisons to find keys or certificates must also be case insensitive.

Windows Specific Technology

Windows has two cryptography technologies that use quite different technologies to protect [[Private Key Component]s.

Cryptographic API (CAPI)

This technology is based on the original bcrypt libraries acquired from RSA in the last century. The Private Key is protected in the Windows Registry as a part of the certificate key store using the Cryptographic Service Provider (CSP) specific to the type of private key. It was extended in later years to handle keys in hardware like smart cards and HSMs, but the marriage was awkward. This was the only technology supported by managed code (dotnet) until net core 2.1 or framework 4.6. Since Microsoft's ASP web platform was build on dot net, this made good key hygiene very difficult for web developers.

Cryptography Next Generation (CNG)

This is new technology that created the abstraction know a a Key Storage Provider (KSP) to differentiate the function of protecting the Private Key Component from the function of storing credentials that could be renew every year while the KSP was unaffected. Now the permissions for each key storage file can be independently set.

function setCertificatePermission {
    param($accountName, $certificate)
        $rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($certificate)
        $fileName = $rsaCert.key.UniqueName
        $path = "$env:ALLUSERSPROFILE\Microsoft\Crypto\Keys\$fileName"
        $permissions = Get-Acl -Path $path
        $access_rule = New-Object System.Security.AccessControl.FileSystemAccessRule($accountName, 'FullControl', 'None', 'None', 'Allow')
        Set-Acl -Path $path -AclObject $permissions
    } else{
            $user = New-Object System.Security.Principal.NTAccount($accountName)
            $accessRule = New-Object System.Security.AccessControl.CryptoKeyAccessRule($user, 'FullControl', 'Allow')
            $store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
            $rwCert = $store.Certificates | where {$_.Thumbprint -eq $certificate.Thumbprint}
            $csp = New-Object System.Security.Cryptography.CspParameters($rwCert.PrivateKey.CspKeyContainerInfo.ProviderType, $rwCert.PrivateKey.CspKeyContainerInfo.ProviderName, $rwCert.PrivateKey.CspKeyContainerInfo.KeyContainerName)
            $csp.Flags = "UseExistingKey","UseMachineKeyStore"
            $csp.CryptoKeySecurity = $rwCert.PrivateKey.CspKeyContainerInfo.CryptoKeySecurity
            $csp.KeyNumber = $rwCert.PrivateKey.CspKeyContainerInfo.KeyNumber
            $rsa2 = New-Object System.Security.Cryptography.RSACryptoServiceProvider($csp)