Posts on this page:

SSL key exchange with and without encryption

Recently, a friend of mine asked a question about key exchange in SSL without encrypting the key. His question came after examining a Key Usage certificate extension setting in the certificate template. There are two options: Allow key exchange only with key encryption and Allow key exchange without key encryption. How it can be possible that the key is not encrypted??? Here is an image of the respective setting:

Key Usage extension configuration in certificate template

read more →

Test web server SSL/TLS protocol support with PowerShell

Recently I was tasked to configure SSL/TLS protocols and cipher suites for internal web servers via Group Policy. At first, we collected a list of web server and web client applications to determine the weakest possible SSL/TLS protocols. Once the list was complete, we deployed sample policy in test OU and finally applied them to the rest domain.

Now I was tasked to scan web servers to determine if they match new security policy. In order to minimize my effort in testing, I wrote a simple PowerShell script that accepts a list of web URLs and tests each host with a list of SSL protocols: SSLv2, SSLv3, TLS 1.0, TLS 1.1 and TLS 1.2. Here is a sample code:

read more →

Welcome to my new web home!


Finally I did it! I burned my old SharePoint blog and R.I.P.?ed my former Russian blog (DasBlog) as promised.

The problem

Just to recall the history. Several years ago I realized that I need a new website/portal to host my stuff. Initially I looked for a ready solution that would match my humble requirements:

  1. It should support hierarchical site directories to organize content;
  2. It should support SQL database;
  3. It should support multi-level hierarchical content categories;
  4. It should support an ability to control rendering;
  5. It should support old URLs and redirect to migrated cont...

read more →

Certificate Rules may not work in Software Restriction Policies


Consider the following scenario. You configured Software Restriction Policies (SRP) to allow run all applications that are signed by the specific signer by creating a Certificate Rule against the signer certificate.

When the policy is refreshed on the client, user cannot run the application, because it is blocked by Software Restriction Policies.



This behavior occurs when the certificate is issued by a Certification Authority (CA) which do not include or provide incorrect issuer information in the Authority Information Access (AIA) extension in the signing certificate. In addition, intermediate CA certificate is not installed in the local store. SRP reads only signing certificate in the digital signature and ignores the rest certificates.

This issue may occur when the signing certificate was issued by Thawte due to their CA certificate distribution policy.


This behavior is by design. No bug fixes are available. See Workaround section for example steps to overcome the issue.


Perform the following steps to install intermediate CA certificate to local certificate store.

Option 1 is a general guidance for intermediate CA certificate retrieval. Option 2 is used only for signing certificates issued by Thawte.

Option 1

Option 2

The following steps can be used to save Thawte Code Signing CA – G2 certificate to a file:

  1. Run Notepad;
  2. Copy the following text and paste it to Notepad:

    -----END CERTIFICATE-----

  3. Click File menu and click Save or Save As...;
  4. In the Save dialog, select the path and file name. Append “.cer” extension to the end of the file name;
  5. In the Save as type drop-down list, select All Files (*.*);
  6. Make sure that Encoding drop-down list is set to ANSI:
  7. Click Save button to save the file.

CA certificate installation instructions:

There are three options to install CA certificate to local certificate store:

  • Option 1 installs CA certificate to local machine only;
  • Option 2 installs CA certificate to a set of computers depending on Group Policy object scope in Active Directory;
  • Option 3 installs CA certificate to all machines in the current Active Directory forest

Option 1

  1. Log on to target computer with local Administrator permissions;
  2. Run Command Prompt in elevated mode;
  3. In the Command Prompt, type the following command:

    certutil -f –addstore CA path\cacertfile.cer

    change “path\cacert.cer” part with actual path and file name.
  4. Close Command Prompt.

Option 2

  1. Log on to a computer where Group Policy management tools are installed with Domain Admins permissions;
  2. Run Group Policy Management console (gpmc.msc);
  3. Edit existing or create a new Group Policy Object (GPO).
  4. In the GPO editor, expand Computer Configuration\Policies\Windows Settings\Security Settings\Public Key Infrastructure.
  5. Under Public Key Infrastructure node right-click on Intermediate Certification Authorities and click Import;
  6. Follow Certificate Import Wizard instructions to import CA certificate;
  7. Close GPO editor and Group Policy Management console.

When completed, refresh the group policy on the target clients by running “gpupdate /force” command.

Option 3

  1. Log on to any Active Directory member with Enterprise Administrator permissions;
  2. Run Command Prompt in elevated mode;
  3. In the Command Prompt, type the following command:

    certutil –dspublish –f path\cacertfile.cer SubCA

    change “path\cacert.cer” part with actual path and file name.
  4. Close command Prompt.

When completed, refresh the group policy on the target clients by running “gpupdate /force” command.

    Note: Option 3 requires that Autoenrollment policy is enabled on clients.

    • Windows XP Professional
    • Windows Server 2003 (all editions)
    • Windows Vista Business, Ultimate, Enterprise
    • Windows Server 2008 (all editions)
    • Windows 7 Professional, Ultimate, Enterprise
    • Windows Server 2008 R2 (all editions)
    • Windows 8 Professional, Enterprise
    • Windows Server 2012 (all editions)
    • Windows 8.1 Professional, Enterprise
    • Windows Server 2012 R2 (all editions)

    Test PFX (PKCS#12) file and PFX password with CryptoAPI in PowerShell

    Today I want to present another useful CryptoAPI functions to use when working with PFX (PKCS#12) certificates.

    1. Determine if the BLOB is PFX without having to pass a password;
    2. Test PFX password.

    Of course, you can try to use appropriate X509Certificate2 class constructor, but this approach is faster and do not require key import in cryptographic provider and other actions performed by X509Certificate2 constructor. This functionality is implemented in two CryptoAPI functions:

    1. PFXIsPFXBlob
    2. PFXVerifyPassword

    And here is complete solution:

    $signature = @"
    [DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool PFXIsPFXBlob(
    [DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool PFXVerifyPassword(
        string szPassword,
        int dwFlags
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct CRYPTOAPI_BLOB {
        public int cbData;
        public IntPtr pbData;
    Add-Type -MemberDefinition $signature -Namespace PKI -Name Crypt32
    function Test-CertIsPfx ([Byte[]]$RawData) {
        # create buffer in an unmanaged memory to store raw data
        $pbData = [Runtime.InteropServices.Marshal]::AllocHGlobal($RawData.Length)
        # copy bytes to unmanaged buffer:
        # create CRYPTOAPI_BLOB structure
        $blob = New-Object PKI.Crypt32+CRYPTOAPI_BLOB -Property @{
            cbData = $RawData.Length
            pbData = $pbData
        # call the PFXVerifyPassword to test the content. The function returns $true
        # if byte array represents PFX file.
        # release unmanaged buffer:
    function Test-PfxPassword ([Byte[]]$RawData, [string]$Password) {
        # create buffer in an unmanaged memory to store raw data
        $pbData = [Runtime.InteropServices.Marshal]::AllocHGlobal($RawData.Length)
        # copy bytes to unmanaged buffer:
        # create CRYPTOAPI_BLOB structure
        $blob = New-Object PKI.Crypt32+CRYPTOAPI_BLOB -Property @{
            cbData = $RawData.Length
            pbData = $pbData
        # call the PFXVerifyPassword to test the password. The function returns $true
        # if password is correct
        [PKI.Crypt32]::PFXVerifyPassword($blob, $Password, 0)
        # release unmanaged buffer:

    and usage:

    [↓] [vPodans] $bytes = [io.file]::ReadAllBytes(".\3.pfx")
    [↓] [vPodans] $bytes2 = [io.file]::ReadAllBytes(".\pem.txt")
    [↓] [vPodans] Test-CertIsPfx $bytes
    [↓] [vPodans] Test-CertIsPfx $bytes2
    [↓] [vPodans] Test-PfxPassword $bytes "1"
    [↓] [vPodans] Test-PfxPassword $bytes "other password"
    [↓] [vPodans]

    Note: PFX files must be stored in a pure binary format. Unlike regular certificates, PFX do not support base64 encoding in files.

    In these examples, I read two files, one PFX, another – “whateverelse” and passed them to Test-CertIsPfx function. As you see, only bytes from “3.pfx” file returned $true. And attempted to guess the password and guessed from the first attempt!!! (joke). This is something you can write during morning coffee/tea :)