---
schema_version: "1"
id: 540f150ef70dcbbd691308bb3de508dd9b3ba8dce6425201c64c4d4c20809a09
title: Verify Unchanged Backups Using Hash Algorithms
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/platform/264-0-0/backup_recover_o_verify_unchanged_backups.md
canonical_url: https://help.salesforce.com/s/articleView?id=platform.backup_recover_o_verify_unchanged_backups.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: d767e41dc2ed3d0ae037bbd67170f42a076ee20032a2293ef4b9f17c4d66a4ce
description: Confirm the integrity of your Salesforce backup data using a cryptographic hash stored on a public ledger. Using blockchain verification helps you meet compliance requirements and prevent fraud by maintaining a time-stamped audit trail.
products:
  - Security
  - Salesforce Platform
release: "264"
---
# Verify Unchanged Backups Using Hash Algorithms

Confirm the integrity of your Salesforce backup data using a cryptographic hash stored on a public ledger. Using blockchain verification helps you meet compliance requirements and prevent fraud by maintaining a time-stamped audit trail.

1. Navigate to the Backup History.
2. Select the backup to verify.
3. Click Integrity details.
4. Click Download zip file.
    
    A Backup Export job will begin.
5. When the job is complete, click the Click here to download link to download the backup files.
6. Sort all files in the backup in ascending order.
7. Hash each file with the SHA-256 algorithm.
    
    Example of the hashed file:
    
    ```
    8c4bdaf46e3764ce4b53bdc9e410d5b6d89fa586bfb418fc572f7b4cedf2d93a
    ```
8. Concatenate the hashes with their object name, separated by a semi-colon (;). Then concatenate all the hashes, each separated by a line break (ASCII 10), without white spaces. Make sure the final line ends with a line break. The concatenated string must be encoded with UTF-8.
    
    Example of the hashed file:
    
    ```
    8c4bdaf46e3764ce4b53bdc9e410d5b6d89fa586bfb418fc572f7b4cedf2d93a;accepted_event_relations.csv.gz dd27948844ce32d5510a4a2d7f1f054c58248e3e754f81330a3a7f33c5d2e6c2;account_brand_shares.csv.gz 2cfa4d7c8d830ccf5a1f9c37d5f1a705d4573269aa6acc9468eda0d99af22842;account_brands.csv.gz
    ```
9. Hash the concatenated hashes with the SHA-256 algorithm.
    
    The final hash should appear similar to the following example:
    
    ```
    4c6d3f1f97e7a6001f9764f08b0b5d9e9a8602b2c5386b02a26c4dc1db749bbf
    ```
    
    The following is an example hash script in Python.
    
    ![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-platform-own_from_salesforce-264-0-0-production-enus/8ac98673-ede2-4046-a41e-2d5c846f24ff/images/icon_note.png)
    
    Note The following is meant to provide an example of how the script could be written and should not be used as-is.
    
    ```
    import hashlib
    import json
    import os
    import argparse
    
    LINE_SEP = "\n"
    BUF_SIZE = 65536
    
    
    def hash_backup(directory_path):
        """
        Hash all .csv.gz files in the specified directory.
        
        Args:
            directory_path (str): Path to directory containing backup files.
        
        Returns:
            str: JSON string containing the backup_hash
        """
        # Check if directory exists
        if not os.path.exists(directory_path):
            raise FileNotFoundError(f"Directory not found: {directory_path}")
        
        if not os.path.isdir(directory_path):
            raise NotADirectoryError(f"Path is not a directory: {directory_path}")
        
        hashes = []  # Local variable instead of global
        
        try:
            for filename in sorted(
                os.listdir(directory_path)
            ):  # loops over each file in directory (backup folder), in ascending order
                if filename.endswith(".csv.gz"):  # only hashes the object (.csv.gz) files
                    file_path = os.path.join(directory_path, filename)
                    sha = hashlib.sha256()
                    
                    try:
                        with open(file_path, "rb") as f:
                            while True:  # reads the file in BUF_SIZE buffers
                                data = f.read(BUF_SIZE)
                                if not data:
                                    break
                                # hashes the file with the SHA-256 algorithm
                                sha.update(data)
                        
                        hashes.append(
                            "{}  {}".format(sha.hexdigest(), filename)
                        )  # adds the hash and object name to the hashes list
                    except (IOError, OSError) as e:
                        print(f"Warning: Could not read file {filename}: {e}")
                        continue
            
            if not hashes:
                raise ValueError(f"No .csv.gz files found in directory: {directory_path}")
            
            hashes_string = (
                LINE_SEP.join(hashes) + LINE_SEP
            )  # concatenates all the hashes in the hashes list
            
            # Replace all double spaces with semicolons (more robust)
            encoded = hashes_string.replace("  ", ";").encode("utf-8")
            
            final_hash = hashlib.sha256(
                encoded
            ).hexdigest()  # hashes the concatenated hashes with the SHA-256 algorithm
            return json.dumps({"backup_hash": final_hash})
            
        except Exception as e:
            raise RuntimeError(f"Error processing directory {directory_path}: {e}")
    
    
    def main():
        parser = argparse.ArgumentParser(description="Hash all .csv.gz files in a directory")
        parser.add_argument("-f", "--file-directory", 
                           required=True,
                           help="Directory containing .csv.gz files to hash")
        
        args = parser.parse_args()
        
        try:
            result = hash_backup(args.file_directory)
            print(f"backup hash: {result}")
        except Exception as e:
            print(f"Error: {e}")
            exit(1)
    
    
    if __name__ == "__main__":
        main()
    ```