Šifrování dat

Tato příručka popisuje interní implementaci šifrovacích algoritmů pro odesílání šifrovaných a podepsaných dat z prohlížeče. Slouží především jako reference při implementaci Twisto API bez použití připravené knihovny. Aktuálně podporujeme dva způsoby šifrování dat, které lze v nastavení měnit. Pokud nemůžete použít hotovou knihovnu pro implementaci Twisto, doporučujeme zvolit SecretBox, který je snazší na implementaci.

PHP knihovna šifrování provádí automaticky a nastavení není potřeba měnit.

AES + HMAC

Data se šifrují pomocí AES-128-CBC a podepisují pomocí HMAC-SHA256.

Šifrování dat

  • Odstraňte z tajného klíče prefix (prvních 8 znaků). Řetězec z hexadecimálního kódu převeďte na binární data. Z těchto dat použijte prvních 16 bajtů jako klíč šifry. Zbytek dat použijte jako sůl pro digest.
  • Vygenerujte kryptograficky náhodný inicializační vektor iv.
  • Pomocí klíče a vektoru iv získejte šifru.
  • Data převeďte na UTF-8 a výsledný řetězec komprimujte knihovnou zlib.
  • Přidejte délku řetězce jako unsigned long int v síťovém pořadí bajtů a na výsledný řetězec aplikujte padding.
  • Text zašifrujte a spolu s vektorem iv a digestem převeďte na Base64
import zlib import struct import base64 import binascii from Crypto import Random from Crypto.Cipher import AES from Crypto.Hash.HMAC import HMAC from Crypto.Hash.SHA256 import SHA256Hash import json # get key and salt key_part = secret_encryption_key[8:] binary_key = binascii.unhexlify(key_part) key, salt = binary_key[:16], binary_key[16:] # Initialization vector iv = Random.new().read(AES.block_size) # get cipher. cipher = AES.new(key, AES.MODE_CBC, iv) # conversion to UTF-8 serialized_data = json.dumps(data).encode('utf-8') # data compression serialized_data = zlib.compress(serialized_data, 9) # attach data size in bytes (big-endian) serialized_data = struct.pack('!L', len(serialized_data)) + serialized_data # checksum digest = HMAC(salt, serialized_data + iv, SHA256Hash()).digest() # padding serialized_data += bytes(16 - len(serialized_data) % 16) # encryption encrypted_data = cipher.encrypt(serialized_data) payload = str(base64.b64encode(iv + digest + encrypted_data), encoding='utf-8')

SecretBox

Šifrování je implementováno open source knihovnou Sodium založenou na kryptografické knihovně NaCl. Knihovna je napsána v C, existuje však mnoho implementací pro další jazyky.

Šifrování dat

  • Odstraňte z tajného klíče prefix (prvních 8 znaků). Řetězec z hexadecimálního kódu převeďte na binární data. Z těchto dat použijte prvních 16 bajtů jako klíč šifry.
  • Vytvořte náhodný nonce pomocí bezpečného generátoru náhodných čísel. Každý nonce lze použít jen jednou. Generátor musí být bezpečný pro kryptografické účely, proto důrazně doporučujeme použít generátor z knihovny Sodium.
  • Zašifrujte pomocí knihovny Sodium.
import binascii from nacl import encoding from nacl.secret import SecretBox from nacl.utils import random # remove prefix key_part = secret_encryption_key[8:] # get binary key en_key = binascii.unhexlify(key_part) # get random nonce box = SecretBox(en_key, encoder=encoding.RawEncoder) nonce = random(SecretBox.NONCE_SIZE) # encryption str = box.encrypt(data, nonce, encoder=encoding.Base64Encoder)