File hash calculation at Secure Exchanges

File hash calculation at Secure Exchanges

At Secure Exchanges, we use a robust and efficient method to calculate the SHA-512 hash of files of all sizes. Our approach ensures data security and integrity while optimizing performance for large files.

Hash Calculation Method

  1. Files of 1 GB or less :

    • For files of size equal to or less than 1 GB, we use a standard method of calculating the SHA-512 hash in a single pass on the entire file.
  2. Files larger than 1 GB :

    • For files larger than 1 GB, we divide the file into 100 MB blocks.
    • We calculate the SHA-512 hash of each block individually.
    • We combine the hashes of each block into a single string.
    • We calculate the final hash of this combined string.

Online Consultation

To offer our users maximum flexibility, anyone with a file can also consult our dedicated page to calculate its hash: Hash Calculator . This service is designed to provide a fast and reliable hash calculation, regardless of file size.

Info
Starting June 24, 2024, we implemented this new hash calculation method to improve performance and the handling of large files. Prior to this date, hashing was calculated using the traditional method. This update reflects our ongoing commitment to optimizing our services to meet the needs of our users.

At Secure Exchanges, we are committed to providing secure and efficient solutions for all your file management needs.

Example Code

Here are some code examples in C#, JavaScript to calculate the SHA-512 hash of a file using our approach.

c#
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Security.Cryptography;
  5. using System.Text;

  6. public static class Hashing
  7. {
  8. public static string GetSHA512OfFile(string filePath)
  9. {
  10. if (File.Exists(filePath))
  11. {
  12. const int chunkSize = 100 * 1024 * 1024; // 100 MB
  13. const long largeFileTrigger = 1000 * 1024 * 1024; // 1 GB
  14. FileInfo fileInfo = new FileInfo(filePath);
  15. long fileSize = fileInfo.Length;

  16. if (fileSize <= largeFileTrigger)
  17. {
  18. // For files smaller than or equal to 1 GB, calculate hash directly
  19. using (var stream = new BufferedStream(File.OpenRead(filePath), chunkSize))
  20. {
  21. return GetSHA512OfStream(stream);
  22. }
  23. }
  24. else
  25. {
  26. // For files larger than 1 GB, use chunked approach
  27. List<string> blockHashes = new List<string>();
  28. using (var stream = new BufferedStream(File.OpenRead(filePath), chunkSize))
  29. {
  30. byte[] buffer = new byte[chunkSize];
  31. int bytesRead;
  32. while ((bytesRead = stream.Read(buffer, 0, chunkSize)) > 0)
  33. {
  34. using (SHA512 sha512 = SHA512.Create())
  35. {
  36. byte[] chunkHash = sha512.ComputeHash(buffer, 0, bytesRead);
  37. blockHashes.Add(BitConverter.ToString(chunkHash).Replace("-", "").ToLower());
  38. }
  39. }
  40. }
  41. // Combine block hashes and calculate final hash
  42. string combinedHashString = string.Join("", blockHashes);
  43. using (SHA512 sha512 = SHA512.Create())
  44. {
  45. byte[] finalHash = sha512.ComputeHash(Encoding.UTF8.GetBytes(combinedHashString));
  46. return BitConverter.ToString(finalHash).Replace("-", "").ToUpper();
  47. }
  48. }
  49. }
  50. else
  51. {
  52. return null;
  53. }
  54. }

  55. public static string GetSHA512OfStream(Stream stream)
  56. {
  57. using (var sha = SHA512.Create())
  58. {
  59. return GetHexaString(sha.ComputeHash(stream));
  60. }
  61. }

  62. private static string GetHexaString(byte[] hash)
  63. {
  64. if (hash != null)
  65. {
  66. StringBuilder sb = new StringBuilder();
  67. for (int i = 0; i < hash.Length; i++)
  68. {
  69. sb.Append(hash[i].ToString("X2"));
  70. }
  71. return sb.ToString();
  72. }
  73. return string.Empty;
    }
    }

Javascript

Quote
  1. var window = self;
  2. var document = {};

  3. onmessage = async function (args) {
  4. var obj = args.data;
  5. let reader = new FileReader();
  6. var hash = {};
  7. var chunkSize = 100 * 1024 * 1024; // 100MB chunk size for large files
  8. var largeFileTrigger = 1000 * 1024 * 1024; // 1GB file will use block approach
  9. var isLargeFile = obj.File.size > largeFileTrigger;

  10. const chunksQuantity = Math.ceil(obj.File.size / chunkSize);
  11. const chunksQueue = new Array(chunksQuantity).fill().map((_, index) => index).reverse();

  12. let blockHashes = [];

  13. reader.onload = async function (evt) {
  14. if (isLargeFile) {
  15. let blockHash = await digestMessage(evt.currentTarget.result);
  16. blockHashes.push(blockHash);
  17. } else {
  18. blockHashes.push(evt.currentTarget.result);
  19. }
  20. readNext();
  21. }

  22. let readNext = async function () {
  23. if (chunksQueue.length > 0) {
  24. const chunkId = chunksQueue.pop();
  25. const sentSize = chunkId * chunkSize;
  26. const chunk = obj.File.slice(sentSize, sentSize + chunkSize);
  27. reader.readAsArrayBuffer(chunk);
  28. } else {
  29. reader.abort();
  30. var hexHash = null;
  31. if (isLargeFile) {
  32. let combinedHashBuffer = new TextEncoder().encode(blockHashes.join(''));
  33. hexHash = await digestMessage(combinedHashBuffer);
  34. } else {
  35. hexHash = await digestMessage(blockHashes[0]);
  36. }

  37. hash.SHA512 = hexHash.toUpperCase();
  38. postMessage({ Hash: hash, File: obj.File, ID: obj.ID, ReturnObject: obj.ReturnObject });
  39. }
  40. }

  41. readNext();
  42. }

  43. // Function to digest message and return hex string
  44. async function digestMessage(buffer) {
  45. const hashBuffer = await crypto.subtle.digest('SHA-512', buffer);
  46. const hashArray = Array.from(new Uint8Array(hashBuffer));
  47. const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
  48. return hashHex;
  49. }

    • Related Articles

    • What are Secure Exchanges?

      Introduction Secure Exchanges is a Canadian company founded in Quebec, specializing in the protection of digital communications and the security of sensitive data. Our technology allows organizations to securely transmit, sign, and receive ...
    • Is Secure Exchanges compatible with Macintosh?

      Secure Exchanges is not compatible with the Mail and Outlook applications on Mac. However, you can log in to Gmail from your browser on Mac, in order to use Secure Exchanges. Here's how to install Secure Exchanges on Gmail.
    • Can Secure Exchanges read my messages?

      No. The messages are end-to-end encrypted. Secure Exchanges cannot read or reconstruct the content.
    • How do I uninstall Secure Exchanges?

      1. Uninstall Secure Exchanges on Outlook (desktop - Windows) Open the control panel Click the Windows "Start" button, then search for and select Control Panel. Access program management In the control panel, select "Programs", then "Uninstall a ...
    • Is it possible to keep copies of confidential exchanges made via Secure Exchanges?

      Our SESAR solution allows you to archive and synchronize all secure exchanges via Secure Exchanges. For more information about this service, please visit the following page: What is the role of SESAR? To purchase a SESAR service, please visit our ...