Code examples

Create the following two files:

notarizer.py

 1import hashlib
 2import os.path
 3import requests
 4import sys
 5
 6# The base URL of the notary service API.
 7base_url = 'https://eu2-cloud.acronis.com/api/notary/v2'
 8# The authentication header for accessing the API.
 9# The value after 'Bearer' is the token generated in "Accessing the API".
10auth = {
11    'Authorization': 'Bearer 8770b34b74f9e4d9424eff50c38182bb4ae7f5596582ae61900b1b6a23e3ec58'
12}
13
14
15def calculate_file_hash(file_path):
16    """Calculates the SHA-256 hash value of file contents."""
17
18    with open(file_path, 'rb') as fd:
19        sha256 = hashlib.sha256()
20        chunk = fd.read(128 * sha256.block_size)
21        while chunk:
22            sha256.update(chunk)
23            chunk = fd.read(128 * sha256.block_size)
24        return sha256.hexdigest()
25
26
27def notarize(file_path):
28    """
29    Notarizes a file by calculating its hash and sending the hash to the notary service.
30    """
31
32    # Create the meta object with the file name and calculated hash value.
33    metadata = {
34        'GUID': os.path.basename(file_path),
35        'eTag': calculate_file_hash(file_path),
36    }
37
38    # Post the object to the notary service. The same object may be posted to the service
39    # multiple times and every time a new certificate is created.
40    try:
41        response = requests.post(f'{base_url}/meta', headers=auth, json=metadata)
42    except requests.ConnectionError:
43        print('No connection to the notary service.',
44              'Try again later or contact your service administrator.')
45        return
46
47    # Check for errors.
48    status_code = response.status_code
49    if status_code == 401:
50        print('Not authorized.')
51        return
52    if status_code == 402:
53        print('The "Notarizations" quota is reached.')
54        return
55    if status_code != 200:
56        print(response.status_code, response.reason)
57        return
58
59    # Convert the JSON text that the response body contains to an object, and then print the ID of the created notarization certificate.
60    print(response.json()['certificate_id'])
61
62
63if __name__ == '__main__':
64    notarize(sys.argv[1])

verifier.py

 1import hashlib
 2import pprint
 3import requests
 4import sys
 5
 6# The base URL of the notary service API.
 7base_url = 'https://eu2-cloud.acronis.com/api/notary/v2'
 8
 9
10def calculate_file_hash(file_path):
11    """Calculates the SHA-256 hash value of file contents."""
12
13    with open(file_path, 'rb') as fd:
14        sha256 = hashlib.sha256()
15        chunk = fd.read(128 * sha256.block_size)
16        while chunk:
17            sha256.update(chunk)
18            chunk = fd.read(128 * sha256.block_size)
19        return sha256.hexdigest()
20
21
22def verify(file_path, certificate_id):
23    """
24    Verifies if a file is notarized by calculating its hash and checking if
25    this hash was written to the Ethereum blockchain during a specific notarization
26    process designated by the notarization certificate ID.
27    """
28
29    # Create the meta object with the file name and calculated hash value.
30    file_hash_data = {
31        'hash': calculate_file_hash(file_path),
32        'certificate_hash': certificate_id,
33    }
34
35    # Post the object to the notary service.
36    try:
37        response = requests.post(f'{base_url}/hashes/verify', json=file_hash_data)
38    except requests.ConnectionError:
39        print('No connection to the notary service.',
40              'Try again later or contact your service administrator.')
41        return
42
43    # Check for errors.
44    status_code = response.status_code
45    if status_code == 404:
46        print('This file has never been notarized.')
47        return
48    if status_code != 200:
49        print(response.status_code, response.reason)
50        return
51
52    # Convert the JSON text that the response body contains to an object,
53    # and then fetch the notarization certificate.
54    certificate = response.json()['certificates'][0]
55
56    if not certificate['txid']:
57        print('The file notarization is in progress.')
58        return
59
60    print('The file is notarized.')
61    pprint.pprint(certificate)
62
63
64if __name__ == '__main__':
65    verify(sys.argv[1], sys.argv[2])

To notarize a file

  1. Start the command line, and then cd to the file’s folder.

  2. Run the following command:

    python notarizer.py <file name>
    

    If no error occurs, the script will output the ID of the notarization certificate that has been created. Otherwise, the script will output the error details.

Use the returned ID, along with the file itself, to verify the file’s authenticity.

To verify the authenticity of a file

  1. Start the command line, and then cd to the file’s folder.

  2. Run the following command:

    python verifier.py <file name> <notarization certificate ID>
    

    The script will output the file notarization status or error details, if any.