Skip to main content
Skip table of contents

Existing CISCO Voice Recording Encryption Configuration Guide

Purpose

This document explains how to encrypt all existing un-encrypted call recordings for VRS (Voice Recording Solution), using a Python-based AES encryption script. This step is necessary to ensure compatibility with the latest version of VRS, which expects all recordings to be encrypted. the Below step can be followed to do all the configuration

1. Python Version

  • Python 3.6 or above

Check version:

CODE
python3 --version 

You should see something like this:

CODE
Python 3.8.10 

If you see an error like:

CODE
command not found: python3 

or if the version is lower than 3.6, proceed with the steps below.

Install or Upgrade Python

CODE
sudo apt-get update sudo apt-get install python3 python3-pip -y

After installing, recheck the version:

CODE
python3 --version

You should see something like this:

CODE
Python 3.8.10 

Verify pip3 is Installed
Run:

CODE
pip3 --version 

If not found, install it:

CODE
sudo apt-get install python3-pip -y

2.Python Dependencies

Install required Python libraries:

CODE
pip3 install cryptography 

If pip3 is not installed:

CODE
sudo apt-get update sudo apt-get install python3-pip 

3. Directory Structure

Here are the directories structure to keep in mind

Item

Path

Encryption Script

/usr/local/freeswitch/scripts/encrypt_calls.py

Bash Script

/usr/local/freeswitch/scripts/encrypt_calls.sh

Cisco Recordings

/var/vrs/recordings/cucmRecording/sessions/

Log File

/var/log/encrypt.log


4. Python Library for SQL Server.

CODE
pip install pyodbc
or
pip3 install pyodbc

5.Install prerequisites for ODBC:

CODE
sudo apt-get update
sudo apt-get install -y unixodbc unixodbc-dev

6.Install curl

CODE
sudo apt-get update
sudo apt-get install -y curl

6.Install Microsoft ODBC Driver for SQL Server (Ubuntu/Debian)

CODE
# Import the Microsoft repo key
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -

# Add the Microsoft SQL Server repository
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list

# Update package lists
sudo apt-get update

# Install ODBC driver 18
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18

Verify Driver Installation

CODE
odbcinst -q -d

Expected result

CODE
[ODBC Driver 18 for SQL Server]

5.Python Encryption Script

Navigate to the following directory and create a folder/directory.

CODE
cd /usr/local/freeswitch/scripts/

create a file with the name encrypt_calls.py

CODE
nano encrypt_calls.py

Now paste the following Python script

CODE
import sys
import os
import logging
import pyodbc
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding

# --- Logging Setup ---
LOG_FILE = "/var/log/encrypt.log"
logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

# --- Constants ---
IV = b'1234567890123456'  # 16 bytes for AES
KEY_HEX = '42066107bda481f0266fd709627faf98b422e29a29b01495daa3ef3640ee6fe6'
DB_CONNECTION_STRING = (
    'DRIVER={ODBC Driver 18 for SQL Server};'#or check the version of Driver and put it
    'SERVER=192.168.1.126,1433;'
    'DATABASE=vrs3;'
    'UID=sa;'
    'PWD=Expertflow;'
    'Encrypt=no;'
    'TrustServerCertificate=yes;'
)

# --- Encryption Function ---
def encrypt_file(file_path: str, key: bytes) -> bool:
    """Encrypts the given file with AES-CFB and prepends the IV."""
    try:
        backend = default_backend()
        cipher = Cipher(algorithms.AES(key), modes.CFB(IV), backend=backend)
        encryptor = cipher.encryptor()

        # Read file contents
        with open(file_path, 'rb') as f:
            data = f.read()

        # Apply PKCS7 padding
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()

        # Encrypt and write back
        encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
        with open(file_path, 'wb') as f:
            f.write(IV + encrypted_data)

        logging.info(f"Successfully encrypted: {file_path}")
        return True

    except Exception as e:
        logging.error(f"Error encrypting {file_path}: {e}")
        return False

# --- Database Update Function ---
def update_encryption_status(file_path: str):
    """Checks DB encryption flag, encrypts file if needed, updates DB."""
    try:
        with pyodbc.connect(DB_CONNECTION_STRING) as conn:
            cursor = conn.cursor()
            file_name = os.path.basename(file_path)

            # Check encryption status
            cursor.execute("""
                SELECT is_encrypted FROM Mixed_Sessions 
                WHERE filename LIKE ?
            """, f"%{file_name}%")
            row = cursor.fetchone()

            if row is None:
                logging.warning(f"No DB entry found for: {file_name}")
                return

            if row[0] == 1:
                logging.info(f"File already encrypted in DB: {file_name}")
                return

            # Proceed with encryption
            key = bytes.fromhex(KEY_HEX)
            if encrypt_file(file_path, key):
                cursor.execute("""
                    UPDATE Mixed_Sessions 
                    SET is_encrypted = 1 
                    WHERE filename LIKE ?
                """, f"%{file_name}%")
                conn.commit()
                logging.info(f"Database updated for: {file_name}")
            else:
                logging.error(f"Failed to encrypt file: {file_name}")

    #except Exception as e:
     #   logging.error(f"DB error for {file_path}: {e}")
    except pyodbc.Error as e:
         for err in e.args:
           logging.error(f"DB error detail: {err}")
    except Exception as e:
         logging.error(f"Unexpected error: {e}")

# --- Main Execution ---
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python3 encrypt_calls.py <file_path>")
        sys.exit(1)

    file_path_arg = sys.argv[1]
    logging.info(f"Starting encryption process for: {file_path_arg}")
    update_encryption_status(file_path_arg)

Now give the permission

CODE
chmod 777 encrypt_calls.py

5.Bash Script to Run Bulk Encryption

Navigate to the following directory.

CODE
cd /usr/local/freeswitch/scripts/

Create a bash script file with the name encrypt_calls.sh

CODE
nano encrypt_calls.sh

Now paste the following bash script.
Note: If you want to keep the backup of the files before running the script, Check the point 7 Backup Option (Highly Recommended)

CODE
#!/bin/bash

ENCRYPT_SCRIPT="/usr/local/freeswitch/scripts/encrypt_calls.py"
TARGET_DIR="/var/vrs/recordings/cucmRecording/sessions"

 #BACKUP_DIR="/var/vrs/recordings/cucmRecording/backup"
 #mkdir -p "$BACKUP_DIR"

for file in "$TARGET_DIR"/*.wav; do
    echo "Encrypting: $file"

    
     #cp "$file" "$BACKUP_DIR/"

    python3 "$ENCRYPT_SCRIPT" "$file"
done

Make the script executable:

CODE
chmod +x encrypt_calls.sh 

6.Running the Script

To start encryption:

CODE
./encrypt_calls.sh

If no errors You’ll see output like

image-20250805-073116.png

All encryption activities are logged into a file:

CODE
/var/log/encrypt.log

7.Backup Option (Highly Recommended)

Before running the encryption script, it is strongly recommended to create a backup of all .wav files. This ensures that if there are any issues (e.g., encrypted files not playing correctly in VRS), you can restore the original unencrypted files easily.

To enable automatic backup, uncomment the following lines in the encrypt_calls.sh script, line 6, 7 and 13:

CODE
# BACKUP_DIR="/var/vrs/recordings/cucmRecording/backup"
# mkdir -p "$BACKUP_DIR"
# cp "$file" "$BACKUP_DIR/"

These lines will:

  • Create a backup directory (if it doesn't exist)

  • Copy each .wav file to the backup folder before encrypting it

8.Restoring from Backup (If Needed)

If any issue occurs after encryption (e.g., recordings are not playable in VRS), you can restore the original un-encrypted files from the backup folder:

CODE
cp /var/vrs/recordings/cucmRecording/backup/*.wav /var/vrs/recordings/cucmRecording/sessions/ 

This will overwrite the encrypted files with the original versions, allowing you to re-test or re-encrypt after correcting the issue.


9.Cleanup (After Validation)

Once all files are encrypted successfully and confirmed playable via the VRS front-end, you can delete the backup folder to free up disk space:

CODE
rm -rf /var/vrs/recordings/cucmRecording/backup
rm /usr/local/freeswitch/scripts/encrypt_calls.py
rm /usr/local/freeswitch/scripts/encrypt_calls.sh

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.