mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
add crypto library
This commit is contained in:
parent
2c6cffcf19
commit
a23c4d4159
17 changed files with 2839 additions and 7 deletions
|
|
@ -14,7 +14,8 @@ Subsections:
|
|||
- [base64](scripting/builtins/libbase64.md)
|
||||
- [bjson, json, toml, yaml](scripting/filesystem.md)
|
||||
- [block](scripting/builtins/libblock.md)
|
||||
- [byteutil](scripting/builtins/libbyteutil.md)
|
||||
- [byteutil](scripting/builtins/libbyteutil.md)
|
||||
- [crypto](scripting/builtins/libcrypto.md)
|
||||
- [cameras](scripting/builtins/libcameras.md)
|
||||
- [ctypes](scripting/builtins/libctypes.md)
|
||||
- [entities](scripting/builtins/libentities.md)
|
||||
|
|
|
|||
140
doc/en/scripting/builtins/libcrypto.md
Normal file
140
doc/en/scripting/builtins/libcrypto.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# *crypto* library
|
||||
|
||||
The library provides common cryptographic functions for mods
|
||||
|
||||
TLS and HTTP are not part of this library. They can use crypto for expensive
|
||||
operations
|
||||
|
||||
Keys, signatures, hashes and encrypted data are passed as regular Lua strings.
|
||||
Strings may contain zero bytes
|
||||
|
||||
The current API version is available in `crypto.API_VERSION`
|
||||
|
||||
## Hashing
|
||||
|
||||
```lua
|
||||
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
|
||||
```
|
||||
|
||||
Supported names are `SHA256`, `SHA384`, `SHA512` and `MD5`
|
||||
|
||||
MD5 is provided for old formats. SHA256 should be used for new data
|
||||
|
||||
Large data can be hashed in parts
|
||||
|
||||
```lua
|
||||
local hash = crypto.hash_new("SHA256")
|
||||
hash:update(part1)
|
||||
hash:update(part2)
|
||||
local result = hash:final()
|
||||
```
|
||||
|
||||
Call `reset` before using the context again
|
||||
|
||||
## Signatures
|
||||
|
||||
```lua
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
Ed25519 keys are 32 bytes and signatures are 64 bytes
|
||||
|
||||
ECDSA supports `P-256`, `P-384` and `P-521`. Public keys use the uncompressed
|
||||
SEC1 format and signatures use DER
|
||||
|
||||
RSA modulus and exponent use big endian. A `salt_length` of `-1` uses the hash
|
||||
size. RSA key generation is not provided, Ed25519 is easier for new keys
|
||||
|
||||
## Key exchange
|
||||
|
||||
```lua
|
||||
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` and `x25519_shared` do the same operation
|
||||
|
||||
Pass the shared secret through HKDF before using it as a key
|
||||
|
||||
## Encryption
|
||||
|
||||
```lua
|
||||
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 accepts 16 and 32 byte keys
|
||||
|
||||
ChaCha20 Poly1305 uses a 32 byte key and a 12 byte nonce
|
||||
|
||||
A 16 byte tag is appended to ciphertext. Decryption returns nothing when the
|
||||
tag is invalid
|
||||
|
||||
Never use the same nonce twice with the same key
|
||||
|
||||
## Other functions
|
||||
|
||||
```lua
|
||||
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, [optional]max_memory: int=0) -> str
|
||||
crypto.features() -> table
|
||||
```
|
||||
|
||||
Use scrypt or PBKDF2 with a random salt for passwords. A regular SHA256 hash is
|
||||
not suitable for password storage
|
||||
|
||||
`features` returns the OpenSSL version and available functions
|
||||
|
||||
An invalid signature returns `false, "invalid_signature"`
|
||||
|
||||
An invalid encryption tag returns `nil, "authentication_failed"`
|
||||
|
||||
Invalid arguments raise a regular Lua error
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
- [bjson, json, toml, yaml](scripting/filesystem.md)
|
||||
- [block](scripting/builtins/libblock.md)
|
||||
- [byteutil](scripting/builtins/libbyteutil.md)
|
||||
- [crypto](scripting/builtins/libcrypto.md)
|
||||
- [cameras](scripting/builtins/libcameras.md)
|
||||
- [ctypes](scripting/builtins/libctypes.md)
|
||||
- [entities](scripting/builtins/libentities.md)
|
||||
|
|
|
|||
159
doc/ru/scripting/builtins/libcrypto.md
Normal file
159
doc/ru/scripting/builtins/libcrypto.md
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
# Библиотека *crypto*
|
||||
|
||||
Библиотека предоставляет основные криптографические функции для модов
|
||||
|
||||
TLS и HTTP в нее не входят. Эти протоколы используют crypto для тяжелых
|
||||
вычислений
|
||||
|
||||
Все бинарные значения передаются обычными Lua строками. Это касается ключей,
|
||||
подписей, хешей и зашифрованных данных. Строки могут содержать нулевые байты
|
||||
|
||||
Текущая версия API находится в `crypto.API_VERSION`
|
||||
|
||||
## Хеширование
|
||||
|
||||
```lua
|
||||
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
|
||||
|
||||
Большой файл можно передавать частями
|
||||
|
||||
```lua
|
||||
local hash = crypto.hash_new("SHA256")
|
||||
|
||||
hash:update(part1)
|
||||
hash:update(part2)
|
||||
|
||||
local result = hash:final()
|
||||
```
|
||||
|
||||
После `final` контекст можно очистить через `reset`
|
||||
|
||||
## Подписи
|
||||
|
||||
```lua
|
||||
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 байта
|
||||
|
||||
```lua
|
||||
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 формате
|
||||
|
||||
```lua
|
||||
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
|
||||
|
||||
## Обмен ключами
|
||||
|
||||
```lua
|
||||
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
|
||||
|
||||
## Шифрование
|
||||
|
||||
```lua
|
||||
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 с тем же ключом
|
||||
|
||||
## Остальные функции
|
||||
|
||||
```lua
|
||||
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 ошибку
|
||||
Loading…
Add table
Add a link
Reference in a new issue