Š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)