5.9 KiB
Библиотека crypto
Библиотека предоставляет основные криптографические функции для модов
TLS и HTTP в нее не входят. Эти протоколы используют crypto для тяжелых вычислений
Все бинарные значения передаются обычными Lua строками. Это касается ключей, подписей, хешей и зашифрованных данных. Строки могут содержать нулевые байты
Текущая версия API находится в crypto.API_VERSION
Хеширование
crypto.sha256(data: str) -> str
crypto.sha384(data: str) -> str
crypto.sha512(data: str) -> str
crypto.md5(data: str) -> str
crypto.hash(hash: str, data: str) -> str
crypto.hmac(hash: str, key: str, data: str) -> str
Поддерживаются SHA256, SHA384, SHA512 и MD5
MD5 нужен для совместимости со старыми форматами. Для новых данных лучше использовать SHA256
Большой файл можно передавать частями
local hash = crypto.hash_new("SHA256")
hash:update(part1)
hash:update(part2)
local result = hash:final()
После final контекст можно очистить через reset
Подписи
crypto.ed25519_keypair() -> private_key, public_key
crypto.ed25519_public(private_key: str) -> str
crypto.ed25519_sign(private_key: str, message: str) -> str
crypto.ed25519_verify(public_key: str, message: str, signature: str)
-> true
-> false, error
Ключи Ed25519 имеют длину 32 байта. Подпись имеет длину 64 байта
crypto.ecdsa_keypair(curve: str) -> private_key, public_key
crypto.ecdsa_public(curve: str, private_key: str) -> str
crypto.ecdsa_sign(curve: str, private_key: str, message: str, hash: str) -> str
crypto.ecdsa_verify(curve: str, public_key: str, message: str,
signature: str, hash: str)
-> true
-> false, error
Доступны кривые P-256, P-384 и P-521
Публичный ключ ECDSA записывается как несжатая SEC1 точка. Подпись хранится в DER формате
crypto.rsa_pkcs1_verify(hash: str, modulus: str, exponent: str,
message: str, signature: str)
-> true
-> false, error
crypto.rsa_pss_verify(hash: str, modulus: str, exponent: str,
message: str, signature: str, salt_length: int)
-> true
-> false, error
Модуль и экспонента RSA передаются в big endian. Значение salt_length = -1
использует размер хеша
Генерации RSA ключей в библиотеке нет. Для новых ключей проще использовать Ed25519
Обмен ключами
crypto.x25519_keypair() -> private_key, public_key
crypto.x25519_public(private_key: str) -> str
crypto.x25519(private_key: str, peer_public_key: str) -> str
crypto.x25519_shared(private_key: str, peer_public_key: str) -> str
crypto.p256_keypair() -> private_key, public_key
crypto.p256_public(private_key: str) -> str
crypto.p256_shared(private_key: str, peer_public_key: str) -> str
x25519 и x25519_shared выполняют одну и ту же операцию
Общий секрет не стоит использовать как готовый ключ. Сначала его нужно обработать через HKDF
Шифрование
crypto.aes_gcm_encrypt(key: str, nonce: str, aad: str, plaintext: str) -> str
crypto.aes_gcm_decrypt(key: str, nonce: str, aad: str, ciphertext: str)
-> plaintext
-> nil, error
crypto.chacha20_poly1305_encrypt(key: str, nonce: str, aad: str,
plaintext: str) -> str
crypto.chacha20_poly1305_decrypt(key: str, nonce: str, aad: str,
ciphertext: str)
-> plaintext
-> nil, error
AES GCM принимает ключи размером 16 или 32 байта
ChaCha20 Poly1305 использует ключ размером 32 байта и nonce размером 12 байт
В конец зашифрованных данных добавляется тег размером 16 байт. При неверном теге функция расшифровки ничего не возвращает
Нельзя повторно использовать один nonce с тем же ключом
Остальные функции
crypto.random_bytes(length: int) -> str
crypto.constant_time_equal(left: str, right: str) -> bool
crypto.hkdf_extract(hash: str, salt: str, ikm: str) -> str
crypto.hkdf_expand(hash: str, prk: str, info: str, length: int) -> str
crypto.pbkdf2(hash: str, password: str, salt: str,
iterations: int, length: int) -> str
crypto.scrypt(password: str, salt: str, n: int, r: int, p: int,
length: int, [опционально]max_memory: int=0) -> str
crypto.features() -> table
Для хранения паролей следует использовать scrypt или PBKDF2 со случайной солью. Обычный SHA256 для паролей не подходит
features возвращает версию OpenSSL и список доступных возможностей. Это
можно использовать если мод запускается на разных сборках движка
Неверная подпись возвращает false, "invalid_signature"
Неверный тег при расшифровке возвращает nil, "authentication_failed"
Ошибки в аргументах вызывают обычную Lua ошибку