docs: add README.md
This commit is contained in:
170
README.md
170
README.md
@@ -1,39 +1,149 @@
|
|||||||
<!--
|
# PotatoPassCore
|
||||||
This README describes the package. If you publish this package to pub.dev,
|
|
||||||
this README's contents appear on the landing page for your package.
|
|
||||||
|
|
||||||
For information about how to write a good package README, see the guide for
|
Core библиотека на Dart для экосистемы **PotatoPass** (электронные пропуска и системы контроля доступа).
|
||||||
[writing package pages](https://dart.dev/tools/pub/writing-package-pages).
|
|
||||||
|
|
||||||
For general information about developing packages, see the Dart guide for
|
Содержит реализацию бинарного протокола v1.0, 6-битную оптимизацию текста, генерацию асимметричных ключей и подписей Ed25519, а также средства сериализации/десериализации.
|
||||||
[creating packages](https://dart.dev/guides/libraries/create-packages)
|
|
||||||
and the Flutter guide for
|
|
||||||
[developing packages and plugins](https://flutter.dev/to/develop-packages).
|
|
||||||
-->
|
|
||||||
|
|
||||||
TODO: Put a short description of the package here that helps potential users
|
---
|
||||||
know whether this package might be useful for them.
|
|
||||||
|
|
||||||
## Features
|
## Подключение к проектам
|
||||||
|
|
||||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
Добавление заывисимости в `pubspec.yaml`:
|
||||||
|
|
||||||
## Getting started
|
```yaml
|
||||||
|
dependencies:
|
||||||
TODO: List prerequisites and provide or point to information on how to
|
potato_pass_core:
|
||||||
start using the package.
|
git:
|
||||||
|
url: https://git.mr-potato.ru/PotatoPass/PotatoPassCore.git
|
||||||
## Usage
|
ref: stable
|
||||||
|
|
||||||
TODO: Include short and useful examples for package users. Add longer examples
|
|
||||||
to `/example` folder.
|
|
||||||
|
|
||||||
```dart
|
|
||||||
const like = 'sample';
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Additional information
|
---
|
||||||
|
|
||||||
TODO: Tell users more about the package: where to find more information, how to
|
## Спецификация Бинарного Протокола
|
||||||
contribute to the package, how to file issues, what response they can expect
|
|
||||||
from the package authors, and more.
|
Формат разработан для сверхплотной упаковки данных пропуска в 2D-коды
|
||||||
|
|
||||||
|
### Структура Байтового Массива (Binary Layout)
|
||||||
|
|
||||||
|
| Секция | Длина (Байты) | Описание |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **1. Текстовый блок** | Динамическая (~20–45B) | 5 полей текста с 1-байтовым префиксом длины (6-битное кодирование) |
|
||||||
|
| **2. Блок доступа** | Динамическая (~3–33B) | `1B` длина маски $N$ + $N$ байт битовой маски зон ($1 \text{ бит} = 1 \text{ зона}$) |
|
||||||
|
| **3. Публичный ключ** | `32B` | 32 байта Ed25519 Public Key клиента (уникальный ID пропуска) |
|
||||||
|
| **4. Подпись СБ** | `64B` | Подпись Службы Безопасности (подписывает секции с 1 по 3) |
|
||||||
|
| **5. Подпись Соли** | `64B` | Подпись Клиента (подписывает `Соль (16B)` + `Подпись СБ (64B)`) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6-битный кодировщик текста (`CompactTextEncoder`)
|
||||||
|
|
||||||
|
Для кириллицы стандартный UTF-8 использует 2 байта (16 бит) на символ. `CompactTextEncoder` сжимает 4 символа в 3 байта (6 бит на символ), давая **62% экономии места**.
|
||||||
|
|
||||||
|
### Словарь символов (64 значения = $2^6$):
|
||||||
|
|
||||||
|
```text
|
||||||
|
0..32 : А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
|
||||||
|
33..58 : A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
||||||
|
59..63 : [Пробел] - . , _ (подчеркивание/заполнитель)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Криптографическая модель подписей (Ed25519)
|
||||||
|
|
||||||
|
В системе используются две цифровые подписи для защиты от подделки и копирования:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. [ Текст + Зоны + PubKey Клиента ] ──────────────► Подпись СБ (64B)
|
||||||
|
|
||||||
|
2. [ Challenge Salt (16B) + Подпись СБ (64B) ] ───────────────► Подпись Соли Клиентом (64B)
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **`securityDepartmentSignature` (Подпись СБ):** Доказывает, что ФИО, должность и зоны доступа утверждены Службой Безопасности и не изменены владельцем.
|
||||||
|
2. **`challengeSignature` (Подпись Соли):** Доказывает, что пропуск предъявляет именно его владелец с помощью своего приватного ключа. Одноразовая соль (16B) сгорает каждые 10 секунд, делая скриншоты и фото кода бесполезными.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Примеры использования API
|
||||||
|
|
||||||
|
### 1. Работа с 6-битным кодировщиком текста
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:potato_pass_core/potato_pass_core.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Упаковка строки в 6-битные байты
|
||||||
|
final Uint8List encoded = CompactTextEncoder.encode('Иванов Иван');
|
||||||
|
|
||||||
|
// Распаковка обратно в строку
|
||||||
|
final String decoded = CompactTextEncoder.decode(encoded); // "ИВАНОВ ИВАН"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Генерация ключей и подпись (Ed25519)
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:cryptography/cryptography.dart';
|
||||||
|
import 'package:potato_pass_core/potato_pass_core.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
// Генерация пары ключей
|
||||||
|
final SimpleKeyPair keyPair = await CryptoService.generateKeyPair();
|
||||||
|
final Uint8List pubKeyBytes = await CryptoService.getPublicKeyBytes(keyPair);
|
||||||
|
|
||||||
|
// Подпись сообщения
|
||||||
|
final List<int> message = [1, 2, 3, 4, 5];
|
||||||
|
final Uint8List signature = await CryptoService.sign(
|
||||||
|
message: message,
|
||||||
|
keyPair: keyPair,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Проверка подписи
|
||||||
|
final bool isValid = await CryptoService.verify(
|
||||||
|
message: message,
|
||||||
|
signatureBytes: signature,
|
||||||
|
publicKeyBytes: pubKeyBytes,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Полный цикл сериализации и проверки пропуска
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:potato_pass_core/potato_pass_core.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
// Генерация маски зон доступа (разрешаем зоны 1, 5, 10)
|
||||||
|
final Uint8List zoneMask = PassPayload.createZoneMask([1, 5, 10]);
|
||||||
|
|
||||||
|
// Создание объекта пропуска
|
||||||
|
final pass = PassPayload(
|
||||||
|
lastName: 'Иванов',
|
||||||
|
firstName: 'Иван',
|
||||||
|
middleName: 'Иванович',
|
||||||
|
position: 'Инженер',
|
||||||
|
department: 'Отдел ИТ',
|
||||||
|
zoneMask: zoneMask,
|
||||||
|
clientPublicKey: clientPubKeyBytes,
|
||||||
|
securityDepartmentSignature: sbSignatureBytes,
|
||||||
|
challengeSignature: clientChallengeSigBytes,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Упаковка в байты для DataMatrix / BLE
|
||||||
|
final Uint8List binaryPayload = BinarySerializer.serialize(pass);
|
||||||
|
|
||||||
|
// Распаковка из байтов на стороне Контролера
|
||||||
|
final PassPayload restoredPass = BinarySerializer.deserialize(binaryPayload);
|
||||||
|
|
||||||
|
// Проверка прав доступа в зону 5
|
||||||
|
if (restoredPass.hasZoneAccess(5)) {
|
||||||
|
print('Доступ разрешен!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user