ver 0.0.1

This commit is contained in:
2026-08-09 23:47:39 +03:00
parent 411b00c3ee
commit 8c431c1742
6 changed files with 506 additions and 3 deletions

View File

@@ -1,9 +1,10 @@
import 'dart:typed_data';
import 'package:potato_pass_core/potato_pass_core.dart';
import 'package:cryptography/cryptography.dart';
import 'package:test/test.dart';
void main() {
group('CompactTextEncoder Tests', () {
group('6-и битный колдировщик', () {
test('Кодирование и декодирование русской строки', () {
const input = 'ИВАНОВ ИВАН ИВАНОВИЧ';
@@ -50,4 +51,281 @@ void main() {
expect(decoded, equals('АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ .-,'));
});
});
group('Тест полного цикла', () {
test('Нормальные данные', () async {
// 1. Создаем ключи СБ и Клиента
final SimpleKeyPair sbKeyPair = await CryptoService.generateKeyPair();
final Uint8List sbPubKey = await CryptoService.getPublicKeyBytes(sbKeyPair);
final SimpleKeyPair clientKeyPair = await CryptoService.generateKeyPair();
final Uint8List clientPubKey = await CryptoService.getPublicKeyBytes(clientKeyPair);
// 2. СБ создает маску зон доступа (разрешаем зоны 1, 5, 10)
final Uint8List zoneMask = PassPayload.createZoneMask([1, 5, 10]);
// 3. Формируем тело пропуска для СБ
final passWithoutSignatures = PassPayload(
lastName: 'Иванов',
firstName: 'Иван',
middleName: 'Иванович',
position: 'Инженер',
department: 'Отдел ИТ',
zoneMask: zoneMask,
clientPublicKey: clientPubKey,
securityDepartmentSignature: Uint8List(64),
challengeSignature: Uint8List(64),
);
// 4. Служба Безопасности подписывает тело пропуска
final Uint8List sbSignedBodyBytes = passWithoutSignatures.getSignedBodyBytes();
final Uint8List securityDepartmentSignature = await CryptoService.sign(
message: sbSignedBodyBytes,
keyPair: sbKeyPair,
);
// 5. Контролер/Сервер дает соль
final Uint8List challengeSalt = SaltGenerator.generate(16);
// 6. Клиент подписывает (Соль + Подпись СБ) своим приватным ключом
final List<int> challengeMessage = [...challengeSalt, ...securityDepartmentSignature];
final Uint8List challengeSignature = await CryptoService.sign(
message: challengeMessage,
keyPair: clientKeyPair,
);
// 7. Собираем итоговый рабочий пропуск
final PassPayload fullPass = PassPayload(
lastName: 'Иванов',
firstName: 'Иван',
middleName: 'Иванович',
position: 'Инженер',
department: 'Отдел ИТ',
zoneMask: zoneMask,
clientPublicKey: clientPubKey,
securityDepartmentSignature: securityDepartmentSignature,
challengeSignature: challengeSignature,
);
// 8. СЕРИАЛИЗАЦИЯ В БИТЫ
final Uint8List binaryPayload = BinarySerializer.serialize(fullPass);
// 9. ДЕСЕРИАЛИЗАЦИЯ ИЗ БИТОВ
final PassPayload restoredPass = BinarySerializer.deserialize(binaryPayload);
// --- ПРОВЕРКА ДАННЫХ ---
expect(restoredPass.lastName, equals('ИВАНОВ'));
expect(restoredPass.firstName, equals('ИВАН'));
expect(restoredPass.position, equals('ИНЖЕНЕР'));
expect(restoredPass.department, equals('ОТДЕЛ ИТ'));
// --- ПРОВЕРКА ЗОН ДОСТУПА ---
expect(restoredPass.hasZoneAccess(1), isTrue);
expect(restoredPass.hasZoneAccess(5), isTrue);
expect(restoredPass.hasZoneAccess(10), isTrue);
expect(restoredPass.hasZoneAccess(2), isFalse);
// --- ПРОВЕРКА КРИПТОГРАФИИ (1): ВАЛИДНОСТЬ ПОДПИСИ СЛУЖБЫ БЕЗОПАСНОСТИ ---
final bool isSecuritySignatureValid = await CryptoService.verify(
message: restoredPass.getSignedBodyBytes(),
signatureBytes: restoredPass.securityDepartmentSignature,
publicKeyBytes: sbPubKey,
);
expect(isSecuritySignatureValid, isTrue);
// --- ПРОВЕРКА КРИПТОГРАФИИ (2): ВАЛИДНОСТЬ ПОДПИСИ СОЛИ КЛИЕНТОМ ---
final List<int> restoredChallengeMessage = [...challengeSalt, ...restoredPass.securityDepartmentSignature];
final bool isClientSignatureValid = await CryptoService.verify(
message: restoredChallengeMessage,
signatureBytes: restoredPass.challengeSignature,
publicKeyBytes: restoredPass.clientPublicKey,
);
expect(isClientSignatureValid, isTrue);
});
test('Пустые строки', () async {
// 1. Создаем ключи СБ и Клиента
final SimpleKeyPair sbKeyPair = await CryptoService.generateKeyPair();
final Uint8List sbPubKey = await CryptoService.getPublicKeyBytes(sbKeyPair);
final SimpleKeyPair clientKeyPair = await CryptoService.generateKeyPair();
final Uint8List clientPubKey = await CryptoService.getPublicKeyBytes(clientKeyPair);
// 2. СБ создает маску зон доступа (разрешаем зоны 1, 5, 10)
final Uint8List zoneMask = PassPayload.createZoneMask([1, 5, 10]);
// 3. Формируем тело пропуска для СБ
final passWithoutSignatures = PassPayload(
lastName: '',
firstName: '',
middleName: '',
position: '',
department: '',
zoneMask: zoneMask,
clientPublicKey: clientPubKey,
securityDepartmentSignature: Uint8List(64),
challengeSignature: Uint8List(64),
);
// 4. Служба Безопасности подписывает тело пропуска
final Uint8List sbSignedBodyBytes = passWithoutSignatures.getSignedBodyBytes();
final Uint8List securityDepartmentSignature = await CryptoService.sign(
message: sbSignedBodyBytes,
keyPair: sbKeyPair,
);
// 5. Контролер/Сервер дает соль
final Uint8List challengeSalt = SaltGenerator.generate(16);
// 6. Клиент подписывает (Соль + Подпись СБ) своим приватным ключом
final List<int> challengeMessage = [...challengeSalt, ...securityDepartmentSignature];
final Uint8List challengeSignature = await CryptoService.sign(
message: challengeMessage,
keyPair: clientKeyPair,
);
// 7. Собираем итоговый рабочий пропуск
final PassPayload fullPass = PassPayload(
lastName: '',
firstName: '',
middleName: '',
position: '',
department: '',
zoneMask: zoneMask,
clientPublicKey: clientPubKey,
securityDepartmentSignature: securityDepartmentSignature,
challengeSignature: challengeSignature,
);
// 8. СЕРИАЛИЗАЦИЯ В БИТЫ
final Uint8List binaryPayload = BinarySerializer.serialize(fullPass);
// 9. ДЕСЕРИАЛИЗАЦИЯ ИЗ БИТОВ
final PassPayload restoredPass = BinarySerializer.deserialize(binaryPayload);
// --- ПРОВЕРКА ДАННЫХ ---
expect(restoredPass.lastName, equals(''));
expect(restoredPass.firstName, equals(''));
expect(restoredPass.position, equals(''));
expect(restoredPass.department, equals(''));
// --- ПРОВЕРКА ЗОН ДОСТУПА ---
expect(restoredPass.hasZoneAccess(1), isTrue);
expect(restoredPass.hasZoneAccess(5), isTrue);
expect(restoredPass.hasZoneAccess(10), isTrue);
expect(restoredPass.hasZoneAccess(2), isFalse);
// --- ПРОВЕРКА КРИПТОГРАФИИ (1): ВАЛИДНОСТЬ ПОДПИСИ СЛУЖБЫ БЕЗОПАСНОСТИ ---
final bool isSecuritySignatureValid = await CryptoService.verify(
message: restoredPass.getSignedBodyBytes(),
signatureBytes: restoredPass.securityDepartmentSignature,
publicKeyBytes: sbPubKey,
);
expect(isSecuritySignatureValid, isTrue);
// --- ПРОВЕРКА КРИПТОГРАФИИ (2): ВАЛИДНОСТЬ ПОДПИСИ СОЛИ КЛИЕНТОМ ---
final List<int> restoredChallengeMessage = [...challengeSalt, ...restoredPass.securityDepartmentSignature];
final bool isClientSignatureValid = await CryptoService.verify(
message: restoredChallengeMessage,
signatureBytes: restoredPass.challengeSignature,
publicKeyBytes: restoredPass.clientPublicKey,
);
expect(isClientSignatureValid, isTrue);
});
test('Пустые зоны', () async {
// 1. Создаем ключи СБ и Клиента
final SimpleKeyPair sbKeyPair = await CryptoService.generateKeyPair();
final Uint8List sbPubKey = await CryptoService.getPublicKeyBytes(sbKeyPair);
final SimpleKeyPair clientKeyPair = await CryptoService.generateKeyPair();
final Uint8List clientPubKey = await CryptoService.getPublicKeyBytes(clientKeyPair);
// 2. Заполняем пустые зоны
final Uint8List zoneMask = PassPayload.createZoneMask([]);
// 3. Формируем тело пропуска для СБ
final passWithoutSignatures = PassPayload(
lastName: 'Иванов',
firstName: 'Иван',
middleName: 'Иванович',
position: 'Инженер',
department: 'Отдел ИТ',
zoneMask: zoneMask,
clientPublicKey: clientPubKey,
securityDepartmentSignature: Uint8List(64),
challengeSignature: Uint8List(64),
);
// 4. Служба Безопасности подписывает тело пропуска
final Uint8List sbSignedBodyBytes = passWithoutSignatures.getSignedBodyBytes();
final Uint8List securityDepartmentSignature = await CryptoService.sign(
message: sbSignedBodyBytes,
keyPair: sbKeyPair,
);
// 5. Контролер/Сервер дает соль
final Uint8List challengeSalt = SaltGenerator.generate(16);
// 6. Клиент подписывает (Соль + Подпись СБ) своим приватным ключом
final List<int> challengeMessage = [...challengeSalt, ...securityDepartmentSignature];
final Uint8List challengeSignature = await CryptoService.sign(
message: challengeMessage,
keyPair: clientKeyPair,
);
// 7. Собираем итоговый рабочий пропуск
final PassPayload fullPass = PassPayload(
lastName: 'Иванов',
firstName: 'Иван',
middleName: 'Иванович',
position: 'Инженер',
department: 'Отдел ИТ',
zoneMask: zoneMask,
clientPublicKey: clientPubKey,
securityDepartmentSignature: securityDepartmentSignature,
challengeSignature: challengeSignature,
);
// 8. СЕРИАЛИЗАЦИЯ В БИТЫ
final Uint8List binaryPayload = BinarySerializer.serialize(fullPass);
// 9. ДЕСЕРИАЛИЗАЦИЯ ИЗ БИТОВ
final PassPayload restoredPass = BinarySerializer.deserialize(binaryPayload);
// --- ПРОВЕРКА ДАННЫХ ---
expect(restoredPass.lastName, equals('ИВАНОВ'));
expect(restoredPass.firstName, equals('ИВАН'));
expect(restoredPass.position, equals('ИНЖЕНЕР'));
expect(restoredPass.department, equals('ОТДЕЛ ИТ'));
// --- ПРОВЕРКА ЗОН ДОСТУПА ---
expect(restoredPass.hasZoneAccess(1), isFalse);
expect(restoredPass.hasZoneAccess(2), isFalse);
expect(restoredPass.hasZoneAccess(3), isFalse);
expect(restoredPass.hasZoneAccess(4), isFalse);
expect(restoredPass.hasZoneAccess(5), isFalse);
expect(restoredPass.hasZoneAccess(6), isFalse);
expect(restoredPass.hasZoneAccess(7), isFalse);
// --- ПРОВЕРКА КРИПТОГРАФИИ (1): ВАЛИДНОСТЬ ПОДПИСИ СЛУЖБЫ БЕЗОПАСНОСТИ ---
final bool isSecuritySignatureValid = await CryptoService.verify(
message: restoredPass.getSignedBodyBytes(),
signatureBytes: restoredPass.securityDepartmentSignature,
publicKeyBytes: sbPubKey,
);
expect(isSecuritySignatureValid, isTrue);
// --- ПРОВЕРКА КРИПТОГРАФИИ (2): ВАЛИДНОСТЬ ПОДПИСИ СОЛИ КЛИЕНТОМ ---
final List<int> restoredChallengeMessage = [...challengeSalt, ...restoredPass.securityDepartmentSignature];
final bool isClientSignatureValid = await CryptoService.verify(
message: restoredChallengeMessage,
signatureBytes: restoredPass.challengeSignature,
publicKeyBytes: restoredPass.clientPublicKey,
);
expect(isClientSignatureValid, isTrue);
});
});
}