Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Rewrite PFX using AES256-SHA256

See more PFX/P12 Examples

Demonstrates how to load a .pfx/.p12, examine the encryption algorithm used, and rewrite using aes256-sha256.

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Pfx,
  Chilkat.JsonObject;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  pfx: TPfx;
  json: TJsonObject;

begin
  success := False;

  pfx := TPfx.Create;

  //  Let's load a .pfx and examine the encryption algorithms used to protect the private key:
  success := pfx.LoadPfxFile('qa_data/pfx/test_secret.pfx','secret');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  //  Examine the algorithms:

  //  "pbeWithSHAAnd3_KeyTripleDES_CBC" or "pbes2"?
  WriteLn('Algorithm: ' + pfx.AlgorithmId);

  //  If the algorithm is "pbes2" then examine the actual encryption and HMAC algorithms used within pbes2.
  //  (If the algorithm is NOT "pbes2", then the following properties are meaningless and will not be modified from their previous values prior to loading the PFX.)
  WriteLn('Pbes2CryptAlg: ' + pfx.Pbes2CryptAlg);
  WriteLn('Pbes2HmacAlg: ' + pfx.Pbes2HmacAlg);

  //  Our output so far:

  //  Algorithm: pbeWithSHAAnd3_KeyTripleDES_CBC
  //  Pbes2CryptAlg: aes256-cbc
  //  Pbes2HmacAlg: hmacWithSha256

  //  This tells us that the PFX we loaded was protected using triple-DES with SHA1.
  //  (Most existing .pfx/.p12 files use 3DES w/ SHA1.)
  //  The Pbes2CryptAlg and Pbes2HmacAlg properties do not apply here because the AlgorithmId is not equal to "pbes2".  We can ignore those values.

  //  Examine the last JSON data collected in the call to LoadPfxFile.  This gives us information about what is contained in the PFX, including extended attributes.
  json := TJsonObject.Create;
  pfx.GetLastJsonData(json);

  json.EmitCompact := False;
  WriteLn(json.Emit());

  //  Sample output

  //  Use this online tool to generate parsing code from sample JSON: 
  //  Generate Parsing Code from JSON

  //  {
  //    "authenticatedSafe": {
  //      "contentInfo": [
  //        {
  //          "type": "Data",
  //          "safeBag": [
  //            {
  //              "type": "pkcs8ShroudedKeyBag",
  //              "attrs": {
  //                "localKeyId": "16444216",
  //                "keyContainerName": "{F09B755A-1E90-444D-9851-02B86CA14961}",
  //                "msStorageProvider": "Microsoft Enhanced Cryptographic Provider v1.0"
  //              }
  //            }
  //          ]
  //        },
  //        {
  //          "type": "EncryptedData",
  //          "safeBag": [
  //            {
  //              "type": "certBag",
  //              "attrs": {
  //                "localKeyId": "16444216"
  //              },
  //              "subject": "....",
  //              "serialNumber": "9999999999999999999999999999"
  //            },
  //            {
  //              "type": "certBag",
  //              "attrs": {
  //                "authRootSha256Hash": "0vkOXTXKxNQffUTOZq/4heGBX7M5GFhTqH5mwFyb7x4=",
  //                "friendlyName": "XYZ",
  //                "enhKeyUsage": [
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.2",
  //                    "usage": "clientAuth"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.4",
  //                    "usage": "emailProtection"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.3",
  //                    "usage": "codeSigning"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.8",
  //                    "usage": "timeStamping"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.4.1.311.10.3.4",
  //                    "usage": "encryptedFileSystem"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.5.5.8.2.2",
  //                    "usage": "iKEIntermediate"
  //                  },
  //  
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.6",
  //                    "usage": "ipsecTunnel"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.7",
  //                    "usage": "ipsecUser"
  //                  },
  //                  {
  //                    "oid": "1.3.6.1.5.5.7.3.5",
  //                    "usage": "ipsecEndSystem"
  //                  }
  //                ]
  //              },
  //              "subject": "...",
  //              "serialNumber": "8888888888888888888888888888"
  //            },
  //            {
  //              "type": "certBag",
  //              "subject": "...",
  //              "serialNumber": "777777777777777777777777777"
  //            }
  //          ]
  //        }
  //      ]
  //    }
  //  }

  //  ------------------------------------------------------------------------------------------
  //  OK... now let's change the AlgorithmId to "pbes2" 

  pfx.AlgorithmId := 'pbes2';

  //  We already know from above that the PBES2 crypt and HMAC algorithms are "aes256-cbc" and "hmacWithSha256".
  //  Let's set them anyway just for the example...
  pfx.Pbes2CryptAlg := 'aes256-cbc';
  pfx.Pbes2HmacAlg := 'hmacWithSha256';

  //  Rewrite the PFX using pbes2/aes256 + sha256
  success := pfx.ToFile('secret','qa_output/test_secret_aes256.pfx');
  if (success = False) then
    begin
      WriteLn(pfx.LastErrorText);
      Exit;
    end;

  WriteLn('Success.');


  pfx.Free;
  json.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.