mirror of
https://github.com/bpmbpm/doc.git
synced 2026-04-30 20:40:50 +00:00
467 lines
20 KiB
Markdown
467 lines
20 KiB
Markdown
### cryptcp.exe signature verification
|
||
### 1
|
||
Алгоритм проверки подписи CAdES-XL с учетом того, что TSP должен быть действительным при проверке, а сертификаты подписанта могут быть просрочены.
|
||
|
||
## Алгоритм проверки подписи с cryptcp.exe
|
||
|
||
```mermaid
|
||
graph TB
|
||
A[Начало проверки] --> B[Подготовка окружения]
|
||
B --> C[Проверка TSP-метки]
|
||
C --> D{TSP действителен?}
|
||
D -->|Нет| E[❌ Подпись недействительна]
|
||
D -->|Да| F[Проверка целостности]
|
||
F --> G{Подпись соответствует документу?}
|
||
G -->|Нет| E
|
||
G -->|Да| H[Проверка исторической действительности]
|
||
H --> I{Сертификат был действителен при подписании?}
|
||
I -->|Нет| E
|
||
I -->|Да| J[✅ Подпись действительна]
|
||
```
|
||
|
||
## Детальный алгоритм проверки
|
||
|
||
### 1. Подготовка окружения для проверки
|
||
|
||
**Обязательные условия:**
|
||
- Установлен КриптоПРО CSP
|
||
- Установлены актуальные доверенные корневые сертификаты для TSA
|
||
- Доступ к интернету для проверки TSP
|
||
|
||
```bash
|
||
# Проверка установки КриптоПРО
|
||
where cryptcp.exe
|
||
|
||
# Проверка доступности TSP-сервиса
|
||
ping tsp.tensor.ru
|
||
```
|
||
|
||
### 2. Проверка TSP-метки (критически важно)
|
||
|
||
```bash
|
||
# Команда проверки с акцентом на TSP
|
||
cryptcp -verify -cadestype XL -v "signature.sig" "document.pdf"
|
||
```
|
||
|
||
**Что проверяет cryptcp в TSP:**
|
||
- Действительность сертификата TSA на момент проверки
|
||
- Цепочку доверия TSA до доверенного корневого УЦ
|
||
- Корректность временной метки
|
||
- Соответствие хэша подписи
|
||
|
||
### 3. Анализ результатов проверки
|
||
|
||
```python
|
||
import subprocess
|
||
import re
|
||
|
||
def verify_signature(signature_file, document_file):
|
||
"""
|
||
Функция проверки подписи с анализом TSP
|
||
"""
|
||
command = [
|
||
"cryptcp.exe",
|
||
"-verify",
|
||
"-cadestype", "XL",
|
||
"-v", # Детальный вывод
|
||
signature_file,
|
||
document_file
|
||
]
|
||
|
||
result = subprocess.run(command, capture_output=True, text=True, encoding='cp866')
|
||
|
||
return analyze_verification_result(result)
|
||
|
||
def analyze_verification_result(result):
|
||
"""
|
||
Анализ вывода cryptcp с акцентом на TSP
|
||
"""
|
||
output = result.stdout + result.stderr
|
||
|
||
# Критически важные проверки
|
||
checks = {
|
||
'tsp_valid': False,
|
||
'signature_integrity': False,
|
||
'historical_cert_valid': False
|
||
}
|
||
|
||
# Проверка TSP-метки
|
||
if re.search(r'Timestamp.*valid|Временная.*метка.*действительна', output, re.IGNORECASE):
|
||
checks['tsp_valid'] = True
|
||
|
||
# Проверка целостности подписи
|
||
if re.search(r'signature.*valid|подпись.*действительна', output, re.IGNORECASE):
|
||
checks['signature_integrity'] = True
|
||
|
||
# Проверка исторической действительности сертификата
|
||
if re.search(r'certificate.*was.*valid|сертификат.*был.*действителен', output, re.IGNORECASE):
|
||
checks['historical_cert_valid'] = True
|
||
|
||
# Определение итогового результата
|
||
if checks['tsp_valid'] and checks['signature_integrity']:
|
||
return "✅ Подпись действительна"
|
||
else:
|
||
return "❌ Подпись недействительна"
|
||
```
|
||
|
||
### 4. Интерпретация кодов возврата cryptcp.exe
|
||
|
||
```python
|
||
def interpret_exit_code(exit_code):
|
||
"""
|
||
Интерпретация кодов возврата cryptcp.exe
|
||
"""
|
||
exit_codes = {
|
||
0: "✅ Успешная проверка",
|
||
1: "❌ Общая ошибка",
|
||
2: "❌ Неверный формат подписи",
|
||
3: "❌ Проблема с сертификатом",
|
||
4: "❌ Ошибка цепочки доверия",
|
||
5: "❌ Ошибка проверки целостности"
|
||
}
|
||
return exit_codes.get(exit_code, f"❌ Неизвестный код ошибки: {exit_code}")
|
||
```
|
||
|
||
## Практические команды для разных сценариев
|
||
|
||
### Сценарий 1: Базовая проверка
|
||
```bash
|
||
cryptcp -verify -cadestype XL "document.pdf.sig" "document.pdf"
|
||
```
|
||
|
||
### Сценарий 2: Детальная проверка с фокусом на TSP
|
||
```bash
|
||
cryptcp -verify -cadestype XL -v -tsp "http://tsp.tensor.ru" "document.pdf.sig" "document.pdf"
|
||
```
|
||
|
||
### Сценарий 3: Проверка с игнорированием просроченных сертификатов подписанта
|
||
```bash
|
||
# К сожалению, cryptcp не имеет прямого параметра для игнорирования просрочки
|
||
# Но можно использовать кастомное хранилище сертификатов
|
||
cryptcp -verify -cadestype XL -store "My" "document.pdf.sig" "document.pdf"
|
||
```
|
||
|
||
## Полная программа проверки на Python
|
||
|
||
```python
|
||
import subprocess
|
||
import os
|
||
from datetime import datetime
|
||
|
||
class SignatureVerifier:
|
||
def __init__(self, cryptcp_path="cryptcp.exe"):
|
||
self.cryptcp_path = cryptcp_path
|
||
|
||
def verify_signature(self, signature_path, document_path):
|
||
"""
|
||
Полная проверка подписи с акцентом на TSP
|
||
"""
|
||
print(f"🔍 Проверка подписи: {os.path.basename(signature_path)}")
|
||
print(f"📄 Документ: {os.path.basename(document_path)}")
|
||
print(f"🕒 Время проверки: {datetime.now()}")
|
||
|
||
# Проверка существования файлов
|
||
if not os.path.exists(signature_path):
|
||
return "❌ Файл подписи не найден"
|
||
if not os.path.exists(document_path):
|
||
return "❌ Файл документа не найден"
|
||
|
||
# Выполнение проверки
|
||
command = [
|
||
self.cryptcp_path,
|
||
"-verify",
|
||
"-cadestype", "XL",
|
||
"-v",
|
||
signature_path,
|
||
document_path
|
||
]
|
||
|
||
try:
|
||
result = subprocess.run(
|
||
command,
|
||
capture_output=True,
|
||
text=True,
|
||
encoding='cp866',
|
||
timeout=30
|
||
)
|
||
|
||
return self.analyze_result(result)
|
||
|
||
except subprocess.TimeoutExpired:
|
||
return "❌ Таймаут проверки"
|
||
except FileNotFoundError:
|
||
return "❌ cryptcp.exe не найден"
|
||
|
||
def analyze_result(self, result):
|
||
"""
|
||
Детальный анализ результатов проверки
|
||
"""
|
||
analysis = {
|
||
'success': result.returncode == 0,
|
||
'exit_code': result.returncode,
|
||
'tsp_status': 'unknown',
|
||
'signature_status': 'unknown',
|
||
'certificate_status': 'unknown'
|
||
}
|
||
|
||
output = result.stdout + result.stderr
|
||
|
||
# Анализ TSP
|
||
if 'timestamp verified' in output.lower() or 'временная метка действительна' in output.lower():
|
||
analysis['tsp_status'] = 'valid'
|
||
elif 'timestamp invalid' in output.lower() or 'временная метка недействительна' in output.lower():
|
||
analysis['tsp_status'] = 'invalid'
|
||
|
||
# Анализ подписи
|
||
if 'signature verified' in output.lower() or 'подпись действительна' in output.lower():
|
||
analysis['signature_status'] = 'valid'
|
||
elif 'signature invalid' in output.lower() or 'подпись недействительна' in output.lower():
|
||
analysis['signature_status'] = 'invalid'
|
||
|
||
# Формирование итогового вердикта
|
||
return self.generate_verdict(analysis, output)
|
||
|
||
def generate_verdict(self, analysis, output):
|
||
"""
|
||
Формирование итогового заключения на основе анализа
|
||
"""
|
||
# Критически важные проверки
|
||
if analysis['tsp_status'] != 'valid':
|
||
return "❌ ПОДПИСЬ НЕДЕЙСТВИТЕЛЬНА: TSP-метка не прошла проверку"
|
||
|
||
if analysis['signature_status'] != 'valid':
|
||
return "❌ ПОДПИСЬ НЕДЕЙСТВИТЕЛЬНА: нарушена целостность подписи"
|
||
|
||
# Если TSP и подпись действительны - подпись считается действительной
|
||
# независимо от статуса сертификата подписанта
|
||
if analysis['success']:
|
||
return "✅ ПОДПИСЬ ДЕЙСТВИТЕЛЬНА"
|
||
else:
|
||
# Даже если cryptcp вернул ошибку, но TSP и подпись действительны,
|
||
# это может быть из-за просроченного сертификата подписанта
|
||
if analysis['tsp_status'] == 'valid' and analysis['signature_status'] == 'valid':
|
||
return "✅ ПОДПИСЬ ДЕЙСТВИТЕЛЬНА (TSP подтвержден, сертификат подписанта мог истечь)"
|
||
else:
|
||
return f"❌ ПОДПИСЬ НЕДЕЙСТВИТЕЛЬНА. Код: {analysis['exit_code']}"
|
||
|
||
# Использование
|
||
if __name__ == "__main__":
|
||
verifier = SignatureVerifier()
|
||
result = verifier.verify_signature("document.pdf.sig", "document.pdf")
|
||
print(result)
|
||
```
|
||
|
||
## Особые случаи и обработка ошибок
|
||
|
||
### Случай 1: Просрочен сертификат подписанта
|
||
```bash
|
||
# cryptcp может вернуть ошибку, но если TSP действителен - подпись сохраняет силу
|
||
cryptcp -verify ...
|
||
# Возвращает код 3, но TSP проверен - подпись ДЕЙСТВИТЕЛЬНА
|
||
```
|
||
|
||
### Случай 2: Недействительный TSP
|
||
```bash
|
||
# Любая ошибка TSP делает подпись недействительной
|
||
cryptcp -verify ...
|
||
# TSP не прошел проверку - подпись НЕДЕЙСТВИТЕЛЬНА
|
||
```
|
||
|
||
### Случай 3: Нарушена целостность
|
||
```bash
|
||
# Изменен документ или подпись
|
||
cryptcp -verify ...
|
||
# Нарушена целостность - подпись НЕДЕЙСТВИТЕЛЬНА
|
||
```
|
||
|
||
## Выводы:
|
||
|
||
1. **TSP-метка должна быть действительной ПРИ ПРОВЕРКЕ** - это критически важно
|
||
2. **Сертификат подписанта** может быть просрочен - важно только его состояние на момент подписания
|
||
3. **Cryptcp.exe** не имеет прямых параметров для игнорирования просрочки сертификатов, но фокус на TSP позволяет корректно оценить юридическую значимость
|
||
4. **Алгоритм проверки** должен в первую очередь анализировать статус TSP и целостность подписи
|
||
|
||
Данный алгоритм обеспечивает корректную проверку юридической значимости электронной подписи в соответствии с требованиями законодательства и учетом долгосрочного хранения документов.
|
||
|
||
### 2
|
||
## Алгоритм проверки электронной подписи с акцентом на TSP
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[Начало проверки подписи] --> B[Подготовка окружения]
|
||
|
||
B --> C[Проверка наличия файлов]
|
||
C --> D{Файлы существуют?}
|
||
D -->|Нет| E[❌ Ошибка: файлы не найдены]
|
||
D -->|Да| F[Запуск cryptcp.exe для проверки]
|
||
|
||
F --> G[Анализ вывода cryptcp]
|
||
|
||
subgraph G [Анализ результатов]
|
||
H[Проверка TSP-метки]
|
||
I[Проверка целостности подписи]
|
||
J[Проверка сертификата подписанта]
|
||
end
|
||
|
||
H --> K{TSP действителен?}
|
||
K -->|Нет| L[❌ Подпись недействительна<br>TSP не прошел проверку]
|
||
|
||
K -->|Да| I
|
||
I --> M{Подпись соответствует документу?}
|
||
M -->|Нет| N[❌ Подпись недействительна<br>Нарушена целостность]
|
||
|
||
M -->|Да| J
|
||
J --> O{Сертификат был действителен<br>на момент подписания?}
|
||
|
||
O -->|Нет| P[❌ Подпись недействительна<br>Сертификат был недействителен]
|
||
O -->|Да| Q[✅ Подпись действительна]
|
||
|
||
style A fill:#e1f5fe
|
||
style L fill:#ffebee
|
||
style N fill:#ffebee
|
||
style P fill:#ffebee
|
||
style Q fill:#e8f5e9
|
||
style H fill:#fff3e0
|
||
style I fill:#fff3e0
|
||
style J fill:#fff3e0
|
||
```
|
||
|
||
## Детализация критических проверок
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[Детали проверок] --> B[TSP-метка]
|
||
A --> C[Целостность подписи]
|
||
A --> D[Сертификат подписанта]
|
||
|
||
subgraph B [Проверка TSP-метки]
|
||
B1[Сертификат TSA действителен]
|
||
B2[Цепочка доверия TSA построена]
|
||
B3[Временная метка корректна]
|
||
B4[Хэш подписи соответствует]
|
||
end
|
||
|
||
subgraph C [Проверка целостности]
|
||
C1[Подпись соответствует документу]
|
||
C2[Формат CAdES-XL корректен]
|
||
C3[Хэш документа не изменен]
|
||
end
|
||
|
||
subgraph D [Проверка сертификата подписанта]
|
||
D1[Вложенный OCSP-ответ действителен]
|
||
D2[Сертификат не был отозван<br>на момент подписания]
|
||
D3[Цепочка была полной<br>на момент подписания]
|
||
end
|
||
|
||
B --> E{✅ TSP действителен?}
|
||
C --> F{✅ Целостность сохранена?}
|
||
D --> G{✅ Сертификат был действителен?}
|
||
|
||
E & F & G --> H[✅ Все проверки пройдены]
|
||
|
||
style B fill:#fff3e0
|
||
style C fill:#fff3e0
|
||
style D fill:#fff3e0
|
||
style H fill:#e8f5e9
|
||
```
|
||
|
||
## Процесс работы с cryptcp.exe
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant П as Программа проверки
|
||
participant C как cryptcp.exe
|
||
participant CSP как КриптоПРО CSP
|
||
participant T как TSA Сервис
|
||
participant Х как Хранилище сертификатов
|
||
|
||
П->>C: Запуск: cryptcp -verify -cadestype XL -v signature.sig document.pdf
|
||
C->>CSP: Декодирование CAdES-XL
|
||
C->>CSP: Извлечение TSP-метки
|
||
C->>T: Проверка сертификата TSA
|
||
T-->>C: Статус сертификата TSA
|
||
C->>Х: Поиск корневых сертификатов TSA
|
||
Х-->>C: Корневые сертификаты
|
||
C->>CSP: Проверка TSP-метки
|
||
CSP-->>C: Результат проверки TSP
|
||
C->>CSP: Проверка целостности подписи
|
||
CSP-->>C: Результат проверки целостности
|
||
C->>CSP: Проверка сертификата подписанта
|
||
CSP-->>C: Результат проверки сертификата
|
||
C-->>П: Код возврата и детальный вывод
|
||
|
||
П->>П: Анализ результатов с акцентом на TSP
|
||
П->>П: Формирование итогового вердикта
|
||
```
|
||
|
||
## Интерпретация результатов
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[Анализ вывода cryptcp.exe] --> B[Поиск ключевых фраз]
|
||
|
||
B --> C[TSP-метка]
|
||
B --> D[Целостность подписи]
|
||
B --> E[Сертификат подписанта]
|
||
|
||
C --> C1[“timestamp verified”<br>“временная метка действительна”]
|
||
C1 --> C2[✅ TSP действителен]
|
||
|
||
D --> D1[“signature verified”<br>“подпись действительна”]
|
||
D1 --> D2[✅ Целостность сохранена]
|
||
|
||
E --> E1[“certificate was valid”<br>“сертификат был действителен”]
|
||
E1 --> E2[✅ Сертификат был действителен]
|
||
|
||
C2 & D2 --> F[✅ Подпись действительна]
|
||
|
||
C --> C3[“timestamp invalid”<br>“временная метка недействительна”]
|
||
C3 --> G[❌ Критическая ошибка TSP]
|
||
|
||
D --> D3[“signature invalid”<br>“подпись недействительна”]
|
||
D3 --> H[❌ Критическая ошибка целостности]
|
||
|
||
E --> E3[“certificate was invalid”<br>“сертификат был недействителен”]
|
||
E3 --> I[❌ Сертификат был недействителен]
|
||
|
||
G --> J[❌ Подпись недействительна]
|
||
H --> J
|
||
I --> J
|
||
|
||
style F fill:#e8f5e9
|
||
style J fill:#ffebee
|
||
style C2 fill:#e8f5e9
|
||
style D2 fill:#e8f5e9
|
||
style E2 fill:#e8f5e9
|
||
style G fill:#ffebee
|
||
style H fill:#ffebee
|
||
style I fill:#ffebee
|
||
```
|
||
|
||
## Критерии юридической значимости
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[Критерии юридической значимости] --> B[Критически важные]
|
||
A --> C[Второстепенные]
|
||
|
||
B --> B1[TSP действителен при проверке]
|
||
B --> B2[Целостность подписи сохранена]
|
||
B --> B3[Сертификат был действителен при подписании]
|
||
|
||
C --> C1[Корневые сертификаты УЦ действительны]
|
||
C --> C2[Сертификат подписанта действителен сейчас]
|
||
C --> C3[Актуальные OCSP-ответы]
|
||
|
||
B1 & B2 & B3 --> D[✅ Юридически значимая подпись]
|
||
|
||
C1 -.->|Не влияет на историческую подпись| D
|
||
C2 -.->|Не влияет на историческую подпись| D
|
||
C3 -.->|Не влияет на историческую подпись| D
|
||
|
||
style B fill:#fff3e0
|
||
style C fill:#f5f5f5
|
||
style D fill:#e8f5e9
|
||
```
|
||
|
||
Этот алгоритм наглядно показывает, что проверка TSP-метки является критически важным этапом, от которого зависит юридическая значимость всей электронной подписи, независимо от текущего статуса других сертификатов.
|