Decoding Encoded VPN SDK Logs

VPN SDK logs on user devices are encoded to protect sensitive information and comply with Apple requirements. However, there may be times during development, debugging, or support when you need to decode these logs. This article explains how to set up your environment and run a Python script to decode VPN SDK logs.

Prerequisites

To decode the logs, you will need:

  • Python 3

  • PyCryptodome library

  • Encoded VPN SDK logs from the user's device

  • Decryption key and initialization vector (obtained from your Pango account representative)

Environment Setup

  1. Install Python 3 using your preferred method. For example, using Homebrew:

brew install python3

Ensure the path for python3 is added to your PATH variable and pip is set to pip3.

  1. Set up your environment with:

python3 -m venv env
. env/bin/activate
  1. Install the PyCryptodome library:

pip install pycryptodome

If you encounter an "externally-managed-environment" error:

error: externally-managed-environment

try:

Obtaining Encoded Logs

The user's device stores logs for the 10 latest VPN sessions. Refer to this guide for detailed instructions on enabling debug logging, obtaining logs, and real-time debugging.

Decoding Logs

  1. Save the decode_logs.py script (provided below) in a convenient folder.

decode_logs.py
  1. Move the encoded logs to a separate folder containing no other files. This can be a subfolder of the script's location.

  2. Create an output folder for the decoded logs. The decoded files will have a "_decrypted" suffix added to their names.

  3. In the Terminal, navigate to the script's folder and run it with the following parameters:

Replace the placeholders with the appropriate paths and decryption parameters.

If successful, you will see output like:

Adding Log Encoding Credentials

Starting from version 6.8.0 of Unified VPN SDK for Apple, it is possible to add CryptographicCredentials for Hydra and WireGuard configurations, as well as Combined configurations. These credentials are used in the process of encoding logs for secure transmission and later decoding them for analysis.

To add custom CryptographicCredentials, you need to create an instance of the CryptographicCredentials class, providing the necessary key and iv values. Then, pass this instance to the logCryptographicCredentials: CryptographicCredentials? property of your configuration:

CryptographicCredentials Format Requirements

For Apple platforms, the CryptographicCredentials have specific format requirements:

Key Format

  • Algorithm: AES256

  • Format: Raw hex string (e.g., "29c2dcbed2d3672ecf1655d6330ae76834d642fb26c5b828caf939337b713af4")

  • Length: 64 characters (32 bytes when decoded)

IV (Initialization Vector) Format

  • Format: Must contain only numeric digits (0-9)

  • Length: Exactly 16 characters

  • Example: "7654321076543210"

Important: The IV numeric-only restriction is an internal limitation specific to this SDK implementation, not a standard cryptographic requirement. This significantly reduces the entropy from 2^96 to approximately 10^16 possible values.

Encryption Details

  • Mode: AES CBC (Cipher Block Chaining)

  • Implementation: Uses CommonCrypto framework (kCCAlgorithmAES)

  • Note: This is not AES-GCM mode

If the validation fails, you may see one of these error messages in logs:

It is important to note that the logCryptographicCredentials property is optional in any configuration and can be omitted. If no custom credentials are provided (i.e., the property is set to nil), default credentials will be used for log encoding. In this case, the encoded logs can only be decoded by the Apple VPN SDK Team upon request from the Partner's development team.

To ensure the validity of the provided CryptographicCredentials, it is recommended to check the isValid property before assigning the credentials to the logCryptographicCredentials property. If the credentials are invalid, you can set the property to nil to use the default credentials.

Troubleshooting

When executing the decode_logs.py script, the following error traceback is observed:

The error indicates that the script is attempting to open a directory ('../logs/decoded') as a file, resulting in an "IsADirectoryError".

To resolve the "IsADirectoryError", follow these steps:

  1. Locate the logs source folder (../logs/). Identify the decoded logs output folder (../logs/decoded/) within the logs source folder.

  2. Move the decoded logs output folder outside of the logs source folder to a separate location.

  3. Update the decode_logs.py script to point to the new location of the decoded logs output folder.

  4. Re-run the decode_logs.py script to verify that the error has been resolved.

Last updated

Was this helpful?