Russain-SSL-Installer/Russain SSL Installer/Program.cs

807 lines
37 KiB
C#
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace CertificateChecker;
class Program
{
static async Task Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
Console.Title = "Certificate Manager";
while (true)
{
Console.Clear();
Console.WriteLine("╔══════════════════════════════════════════════════════════════════════════╗");
Console.WriteLine("║ УПРАВЛЕНИЕ СЕРТИФИКАТАМИ ║");
Console.WriteLine("╚══════════════════════════════════════════════════════════════════════════╝\n");
Console.WriteLine(" 📋 ГЛАВНОЕ МЕНЮ:");
Console.WriteLine(new string('─', 80));
Console.WriteLine(" 1. 🔍 Проверить сертификаты");
Console.WriteLine(" 2. 📥 Установить сертификаты");
Console.WriteLine(" 3. 🗑️ Удалить сертификаты");
Console.WriteLine(" 4. 📊 Показать все установленные сертификаты");
Console.WriteLine(" 5. 🚪 Выход");
Console.WriteLine(new string('─', 80));
Console.Write("\n Ваш выбор: ");
var choice = Console.ReadLine();
switch (choice)
{
case "1":
await CheckCertificatesAsync();
break;
case "2":
await InstallCertificatesAsync();
break;
case "3":
await DeleteCertificatesAsync();
break;
case "4":
await ShowAllInstalledCertificatesAsync();
break;
case "5":
Console.WriteLine("\n До свидания! 👋");
return;
default:
Console.WriteLine("\n ❌ Неверный выбор. Нажмите любую клавишу...");
Console.ReadKey();
break;
}
}
}
/// <summary>
/// Проверка сертификатов
/// </summary>
static async Task CheckCertificatesAsync()
{
Console.Clear();
Console.WriteLine("╔══════════════════════════════════════════════════════════════════════════╗");
Console.WriteLine("║ ПРОВЕРКА СЕРТИФИКАТОВ ║");
Console.WriteLine("╚══════════════════════════════════════════════════════════════════════════╝\n");
var checker = new CertificateChecker();
Console.WriteLine("📂 Загрузка сертификатов из ресурсов...\n");
var certificates = checker.LoadCertificatesFromResources();
if (!certificates.Any())
{
Console.WriteLine("\n❌ Сертификаты не найдены в ресурсах.");
Console.WriteLine("\n💡 Проверьте:");
Console.WriteLine(" 1. Что файл Resources.resx существует");
Console.WriteLine(" 2. Что сертификаты добавлены как ресурсы (тип: byte[])");
Console.WriteLine(" 3. Что ключи ресурсов содержат: cert, ca, root или sub");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
return;
}
Console.WriteLine($"\n✅ Загружено сертификатов: {certificates.Count}\n");
Console.WriteLine(new string('═', 100));
// Проверяем каждый сертификат
var results = new List<CertificateCheckResult>();
for (int i = 0; i < certificates.Count; i++)
{
var cert = certificates[i];
Console.WriteLine($"\n🔍 Проверка сертификата #{i + 1}: {cert.FriendlyName}");
Console.WriteLine(new string('─', 80));
var result = await checker.CheckCertificateInstalledAsync(cert);
results.Add(result);
Console.WriteLine($" 📋 Имя: {result.FriendlyName}");
Console.WriteLine($" 🔑 Отпечаток: {result.Thumbprint}");
Console.WriteLine($" 📅 Действителен: {result.NotBefore:dd.MM.yyyy} → {result.NotAfter:dd.MM.yyyy}");
Console.WriteLine($" 📊 Статус: {(result.IsInstalled ? " УСТАНОВЛЕН" : " НЕ УСТАНОВЛЕН")}");
if (result.IsInstalled)
{
Console.WriteLine($" 📁 Хранилище: {result.StoreLocation}\\{result.StoreName}");
Console.WriteLine($" 🔒 Закрытый ключ: {(result.HasPrivateKey ? " Есть" : " Нет")}");
Console.WriteLine($" ✅ Цепочка: {(result.ChainValidationResult.IsValid ? "Действительна" : "Проблемы")}");
if (result.FoundInStores.Any())
{
Console.WriteLine($" 📂 Найден в хранилищах:");
foreach (var store in result.FoundInStores)
{
Console.WriteLine($" • {store}");
}
}
}
else
{
Console.WriteLine($" ⚠️ Сертификат не найден в системных хранилищах");
if (result.HasPrivateKey)
{
Console.WriteLine($" 💡 Сертификат содержит закрытый ключ и может быть импортирован");
}
}
var daysUntilExpiry = (result.NotAfter - DateTime.Now).Days;
if (daysUntilExpiry < 0)
{
Console.WriteLine($" ⚠️ СЕРТИФИКАТ ПРОСРОЧЕН на {Math.Abs(daysUntilExpiry)} дней!");
}
else if (daysUntilExpiry < 30)
{
Console.WriteLine($" ⚠️ Сертификат истекает через {daysUntilExpiry} дней");
}
else
{
Console.WriteLine($" Сертификат действителен еще {daysUntilExpiry} дней");
}
}
// Выводим итоговую таблицу
Console.WriteLine("\n" + new string('═', 100));
Console.WriteLine("\n📊 ИТОГОВАЯ ТАБЛИЦА ПРОВЕРЕННЫХ СЕРТИФИКАТОВ");
Console.WriteLine(new string('═', 100));
PrintCertificateTable(results);
// Статистика
var installedCount = results.Count(r => r.IsInstalled);
var validCount = results.Count(r => r.IsValid);
var expiredCount = results.Count(r => r.NotAfter < DateTime.Now);
Console.WriteLine("\n" + new string('═', 100));
Console.WriteLine("\n📈 СТАТИСТИКА:");
Console.WriteLine($" • Всего сертификатов: {results.Count}");
Console.WriteLine($" • Установлено: {installedCount} ({(results.Count > 0 ? installedCount * 100 / results.Count : 0)}%)");
Console.WriteLine($" • Не установлено: {results.Count - installedCount} ({(results.Count > 0 ? (results.Count - installedCount) * 100 / results.Count : 0)}%)");
Console.WriteLine($" • Действительные: {validCount} ({(results.Count > 0 ? validCount * 100 / results.Count : 0)}%)");
Console.WriteLine($" • Просроченные: {expiredCount} ({(results.Count > 0 ? expiredCount * 100 / results.Count : 0)}%)");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
}
/// <summary>
/// Установка сертификатов
/// </summary>
static async Task InstallCertificatesAsync()
{
Console.Clear();
Console.WriteLine("╔══════════════════════════════════════════════════════════════════════════╗");
Console.WriteLine("║ УСТАНОВКА СЕРТИФИКАТОВ ║");
Console.WriteLine("╚══════════════════════════════════════════════════════════════════════════╝\n");
var checker = new CertificateChecker();
Console.WriteLine("📂 Загрузка сертификатов из ресурсов...\n");
var certificates = checker.LoadCertificatesFromResources();
if (!certificates.Any())
{
Console.WriteLine("\n❌ Сертификаты не найдены в ресурсах.");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
return;
}
Console.WriteLine($"\n✅ Загружено сертификатов: {certificates.Count}\n");
// Проверяем, какие сертификаты уже установлены
var results = new List<CertificateCheckResult>();
foreach (var cert in certificates)
{
var result = await checker.CheckCertificateInstalledAsync(cert);
results.Add(result);
}
var missing = results.Where(r => !r.IsInstalled).ToList();
if (!missing.Any())
{
Console.WriteLine("✅ Все сертификаты уже установлены!");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
return;
}
Console.WriteLine($"🔧 Обнаружено {missing.Count} сертификатов для установки:\n");
for (int i = 0; i < missing.Count; i++)
{
var cert = missing[i];
Console.WriteLine($" {i + 1}. {cert.FriendlyName}");
Console.WriteLine($" Субъект: {cert.Subject}");
Console.WriteLine($" Действителен до: {cert.NotAfter:dd.MM.yyyy}");
Console.WriteLine();
}
Console.WriteLine(" Выберите действие:");
Console.WriteLine(" [1] Установить все");
Console.WriteLine(" [2] Выборочная установка");
Console.WriteLine(" [3] Отмена");
Console.Write("\n Ваш выбор: ");
var choice = Console.ReadLine();
if (choice == "1")
{
await InstallAllCertificatesAsync(checker, certificates, results);
}
else if (choice == "2")
{
await InstallSelectedCertificatesAsync(checker, certificates, results);
}
else
{
Console.WriteLine("\n Установка отменена.");
}
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
}
/// <summary>
/// Удаление сертификатов
/// </summary>
static async Task DeleteCertificatesAsync()
{
Console.Clear();
Console.WriteLine("╔══════════════════════════════════════════════════════════════════════════╗");
Console.WriteLine("║ УДАЛЕНИЕ СЕРТИФИКАТОВ ║");
Console.WriteLine("╚══════════════════════════════════════════════════════════════════════════╝\n");
var checker = new CertificateChecker();
Console.WriteLine("📂 Загрузка сертификатов из ресурсов...\n");
var certificates = checker.LoadCertificatesFromResources();
if (!certificates.Any())
{
Console.WriteLine("\n❌ Сертификаты не найдены в ресурсах.");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
return;
}
Console.WriteLine($"\n✅ Загружено сертификатов: {certificates.Count}\n");
// Проверяем, какие сертификаты установлены
var results = new List<CertificateCheckResult>();
foreach (var cert in certificates)
{
var result = await checker.CheckCertificateInstalledAsync(cert);
results.Add(result);
}
var installed = results.Where(r => r.IsInstalled).ToList();
if (!installed.Any())
{
Console.WriteLine("⚠️ Нет установленных сертификатов для удаления!");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
return;
}
Console.WriteLine($"🔧 Обнаружено {installed.Count} установленных сертификатов:\n");
for (int i = 0; i < installed.Count; i++)
{
var cert = installed[i];
Console.WriteLine($" {i + 1}. {cert.FriendlyName}");
Console.WriteLine($" Субъект: {cert.Subject}");
Console.WriteLine($" Хранилище: {cert.StoreLocation}\\{cert.StoreName}");
Console.WriteLine($" Действителен до: {cert.NotAfter:dd.MM.yyyy}");
Console.WriteLine();
}
Console.WriteLine(" ⚠️ ВНИМАНИЕ! Удаление сертификатов может нарушить работу приложений!");
Console.WriteLine(" Выберите действие:");
Console.WriteLine(" [1] Удалить все");
Console.WriteLine(" [2] Выборочное удаление");
Console.WriteLine(" [3] Отмена");
Console.Write("\n Ваш выбор: ");
var choice = Console.ReadLine();
if (choice == "1")
{
await DeleteAllCertificatesAsync(checker, certificates, results);
}
else if (choice == "2")
{
await DeleteSelectedCertificatesAsync(checker, certificates, results);
}
else
{
Console.WriteLine("\n Удаление отменено.");
}
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
}
/// <summary>
/// Показать все установленные сертификаты
/// </summary>
static async Task ShowAllInstalledCertificatesAsync()
{
Console.Clear();
Console.WriteLine("╔══════════════════════════════════════════════════════════════════════════╗");
Console.WriteLine("║ ВСЕ УСТАНОВЛЕННЫЕ СЕРТИФИКАТЫ ║");
Console.WriteLine("╚══════════════════════════════════════════════════════════════════════════╝\n");
var checker = new CertificateChecker();
var allCerts = new List<CertificateCheckResult>();
// Проверяем все хранилища
var stores = new[]
{
(StoreName.My, StoreLocation.CurrentUser, "Личные (CurrentUser)"),
(StoreName.My, StoreLocation.LocalMachine, "Личные (LocalMachine)"),
(StoreName.Root, StoreLocation.CurrentUser, "Доверенные корневые (CurrentUser)"),
(StoreName.Root, StoreLocation.LocalMachine, "Доверенные корневые (LocalMachine)"),
(StoreName.TrustedPeople, StoreLocation.CurrentUser, "Доверенные лица (CurrentUser)"),
(StoreName.TrustedPeople, StoreLocation.LocalMachine, "Доверенные лица (LocalMachine)"),
(StoreName.CertificateAuthority, StoreLocation.CurrentUser, "Промежуточные (CurrentUser)"),
(StoreName.CertificateAuthority, StoreLocation.LocalMachine, "Промежуточные (LocalMachine)")
};
Console.WriteLine("📂 Сканирование хранилищ...\n");
foreach (var (storeName, storeLocation, displayName) in stores)
{
try
{
using var store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates;
if (certs.Count > 0)
{
Console.WriteLine($"📁 {displayName} ({certs.Count} сертификатов):");
foreach (var cert in certs)
{
var result = new CertificateCheckResult
{
FriendlyName = string.IsNullOrEmpty(cert.FriendlyName) ? cert.Subject : cert.FriendlyName,
Subject = cert.Subject,
Issuer = cert.Issuer,
Thumbprint = cert.Thumbprint,
NotAfter = cert.NotAfter,
NotBefore = cert.NotBefore,
IsInstalled = true,
StoreName = storeName,
StoreLocation = storeLocation,
HasPrivateKey = cert.HasPrivateKey,
FoundCertificate = cert
};
allCerts.Add(result);
}
foreach (var cert in certs)
{
var name = string.IsNullOrEmpty(cert.FriendlyName) ? "Без имени" : cert.FriendlyName;
Console.WriteLine($" • {name}");
Console.WriteLine($" Отпечаток: {cert.Thumbprint.Substring(0, 16)}...");
Console.WriteLine($" Действителен до: {cert.NotAfter:dd.MM.yyyy}");
Console.WriteLine($" Закрытый ключ: {(cert.HasPrivateKey ? " Есть" : " Нет")}");
Console.WriteLine();
}
}
}
catch
{
// Пропускаем недоступные хранилища
}
}
Console.WriteLine($"\n📊 Всего найдено: {allCerts.Count} сертификатов");
// Статистика
var withPrivateKey = allCerts.Count(c => c.HasPrivateKey);
var expired = allCerts.Count(c => c.NotAfter < DateTime.Now);
Console.WriteLine($" • С закрытым ключом: {withPrivateKey}");
Console.WriteLine($" • Просроченных: {expired}");
Console.WriteLine("\nНажмите любую клавишу для возврата в меню...");
Console.ReadKey();
}
/// <summary>
/// Установка всех сертификатов
/// </summary>
static async Task InstallAllCertificatesAsync(CertificateChecker checker, List<X509Certificate2> certificates, List<CertificateCheckResult> results)
{
Console.WriteLine("\n🔧 НАЧАЛО УСТАНОВКИ ВСЕХ СЕРТИФИКАТОВ...");
Console.WriteLine(new string('─', 80));
var successCount = 0;
var failCount = 0;
for (int i = 0; i < certificates.Count; i++)
{
var cert = certificates[i];
var result = results[i];
if (!result.IsInstalled)
{
Console.WriteLine($"\n 📥 Установка сертификата: {cert.FriendlyName}");
Console.WriteLine($" Субъект: {cert.Subject}");
var installResult = await checker.InstallCertificateWithAutoStoreAsync(cert);
if (installResult.Success)
{
successCount++;
Console.WriteLine($" ✅ Успешно установлен");
foreach (var msg in installResult.Messages)
{
Console.WriteLine($" {msg}");
}
}
else
{
failCount++;
Console.WriteLine($" ❌ Ошибка установки");
foreach (var msg in installResult.Messages)
{
Console.WriteLine($" {msg}");
}
}
}
}
Console.WriteLine($"\n 📊 ИТОГО УСТАНОВЛЕНО: {successCount}, ОШИБОК: {failCount}");
if (failCount == 0)
{
Console.WriteLine("\n 🎉 Все сертификаты успешно установлены!");
}
else
{
Console.WriteLine($"\n ⚠️ {failCount} сертификатов не удалось установить.");
Console.WriteLine(" Попробуйте запустить приложение от имени администратора.");
}
}
/// <summary>
/// Выборочная установка сертификатов
/// </summary>
static async Task InstallSelectedCertificatesAsync(CertificateChecker checker, List<X509Certificate2> certificates, List<CertificateCheckResult> results)
{
var missing = results.Where(r => !r.IsInstalled).ToList();
if (!missing.Any())
{
Console.WriteLine("\n Нет сертификатов для установки.");
return;
}
Console.WriteLine("\n🔧 ВЫБЕРИТЕ СЕРТИФИКАТЫ ДЛЯ УСТАНОВКИ:");
Console.WriteLine(" Введите номера через запятую (например: 1,3,5) или 'all' для всех");
Console.WriteLine(" Доступные сертификаты:");
for (int i = 0; i < missing.Count; i++)
{
Console.WriteLine($" [{i + 1}] {missing[i].FriendlyName}");
}
Console.Write("\n Ваш выбор: ");
var input = Console.ReadLine();
List<int> selectedIndexes = new List<int>();
if (input?.ToLower() == "all")
{
selectedIndexes = Enumerable.Range(0, missing.Count).ToList();
}
else if (!string.IsNullOrEmpty(input))
{
var parts = input.Split(',');
foreach (var part in parts)
{
if (int.TryParse(part.Trim(), out int num) && num > 0 && num <= missing.Count)
{
selectedIndexes.Add(num - 1);
}
}
}
if (!selectedIndexes.Any())
{
Console.WriteLine(" ❌ Не выбрано ни одного сертификата.");
return;
}
Console.WriteLine($"\n Установка {selectedIndexes.Count} сертификатов...");
var successCount = 0;
var failCount = 0;
foreach (var index in selectedIndexes)
{
var result = missing[index];
var cert = certificates.FirstOrDefault(c => c.Thumbprint == result.Thumbprint);
if (cert == null)
{
Console.WriteLine($" ❌ Сертификат {result.FriendlyName} не найден");
failCount++;
continue;
}
Console.WriteLine($"\n 📥 Установка: {cert.FriendlyName}");
var installResult = await checker.InstallCertificateWithAutoStoreAsync(cert);
if (installResult.Success)
{
successCount++;
Console.WriteLine($" ✅ Успешно установлен");
}
else
{
failCount++;
Console.WriteLine($" ❌ Ошибка установки");
foreach (var msg in installResult.Messages)
{
Console.WriteLine($" {msg}");
}
}
}
Console.WriteLine($"\n 📊 УСТАНОВЛЕНО: {successCount}, ОШИБОК: {failCount}");
}
/// <summary>
/// Удаление всех сертификатов
/// </summary>
static async Task DeleteAllCertificatesAsync(CertificateChecker checker, List<X509Certificate2> certificates, List<CertificateCheckResult> results)
{
Console.WriteLine("\n🗑 НАЧАЛО УДАЛЕНИЯ ВСЕХ СЕРТИФИКАТОВ...");
Console.WriteLine(new string('─', 80));
var successCount = 0;
var failCount = 0;
for (int i = 0; i < certificates.Count; i++)
{
var cert = certificates[i];
var result = results[i];
if (result.IsInstalled)
{
Console.WriteLine($"\n 🗑️ Удаление сертификата: {cert.FriendlyName}");
Console.WriteLine($" Хранилище: {result.StoreLocation}\\{result.StoreName}");
try
{
using var store = new X509Store(result.StoreName, result.StoreLocation);
store.Open(OpenFlags.ReadWrite);
var foundCerts = store.Certificates.Find(X509FindType.FindByThumbprint, cert.Thumbprint, false);
if (foundCerts.Count > 0)
{
store.Remove(foundCerts[0]);
successCount++;
Console.WriteLine($" ✅ Успешно удален из {result.StoreLocation}\\{result.StoreName}");
}
else
{
Console.WriteLine($" ⚠️ Сертификат не найден в хранилище");
failCount++;
}
}
catch (Exception ex)
{
failCount++;
Console.WriteLine($" ❌ Ошибка удаления: {ex.Message}");
}
}
}
Console.WriteLine($"\n 📊 ИТОГО УДАЛЕНО: {successCount}, ОШИБОК: {failCount}");
if (failCount == 0)
{
Console.WriteLine("\n 🎉 Все сертификаты успешно удалены!");
}
else
{
Console.WriteLine($"\n ⚠️ {failCount} сертификатов не удалось удалить.");
Console.WriteLine(" Попробуйте запустить приложение от имени администратора.");
}
}
/// <summary>
/// Выборочное удаление сертификатов
/// </summary>
static async Task DeleteSelectedCertificatesAsync(CertificateChecker checker, List<X509Certificate2> certificates, List<CertificateCheckResult> results)
{
var installed = results.Where(r => r.IsInstalled).ToList();
if (!installed.Any())
{
Console.WriteLine("\n Нет сертификатов для удаления.");
return;
}
Console.WriteLine("\n🗑 ВЫБЕРИТЕ СЕРТИФИКАТЫ ДЛЯ УДАЛЕНИЯ:");
Console.WriteLine(" Введите номера через запятую (например: 1,3,5) или 'all' для всех");
Console.WriteLine(" Установленные сертификаты:");
for (int i = 0; i < installed.Count; i++)
{
Console.WriteLine($" [{i + 1}] {installed[i].FriendlyName}");
Console.WriteLine($" Хранилище: {installed[i].StoreLocation}\\{installed[i].StoreName}");
}
Console.Write("\n Ваш выбор: ");
var input = Console.ReadLine();
List<int> selectedIndexes = new List<int>();
if (input?.ToLower() == "all")
{
selectedIndexes = Enumerable.Range(0, installed.Count).ToList();
}
else if (!string.IsNullOrEmpty(input))
{
var parts = input.Split(',');
foreach (var part in parts)
{
if (int.TryParse(part.Trim(), out int num) && num > 0 && num <= installed.Count)
{
selectedIndexes.Add(num - 1);
}
}
}
if (!selectedIndexes.Any())
{
Console.WriteLine(" ❌ Не выбрано ни одного сертификата.");
return;
}
Console.WriteLine($"\n Удаление {selectedIndexes.Count} сертификатов...");
var successCount = 0;
var failCount = 0;
foreach (var index in selectedIndexes)
{
var result = installed[index];
var cert = certificates.FirstOrDefault(c => c.Thumbprint == result.Thumbprint);
if (cert == null)
{
Console.WriteLine($" ❌ Сертификат {result.FriendlyName} не найден");
failCount++;
continue;
}
Console.WriteLine($"\n 🗑️ Удаление: {cert.FriendlyName}");
Console.WriteLine($" Хранилище: {result.StoreLocation}\\{result.StoreName}");
try
{
using var store = new X509Store(result.StoreName, result.StoreLocation);
store.Open(OpenFlags.ReadWrite);
var foundCerts = store.Certificates.Find(X509FindType.FindByThumbprint, cert.Thumbprint, false);
if (foundCerts.Count > 0)
{
store.Remove(foundCerts[0]);
successCount++;
Console.WriteLine($" ✅ Успешно удален");
}
else
{
Console.WriteLine($" ⚠️ Сертификат не найден в хранилище");
failCount++;
}
}
catch (Exception ex)
{
failCount++;
Console.WriteLine($" ❌ Ошибка удаления: {ex.Message}");
}
}
Console.WriteLine($"\n 📊 УДАЛЕНО: {successCount}, ОШИБОК: {failCount}");
}
/// <summary>
/// Выводит таблицу всех проверенных сертификатов
/// </summary>
static void PrintCertificateTable(List<CertificateCheckResult> results)
{
var colWidth = new Dictionary<string, int>
{
["#"] = 4,
["Имя"] = 30,
["Отпечаток"] = 12,
["Действителен до"] = 14,
["Статус"] = 12,
["Ключ"] = 10,
["Цепочка"] = 10,
["Хранилище"] = 20
};
foreach (var result in results)
{
colWidth["Имя"] = Math.Max(colWidth["Имя"], result.FriendlyName.Length + 2);
colWidth["Отпечаток"] = Math.Max(colWidth["Отпечаток"], Math.Min(result.Thumbprint.Length, 14) + 2);
colWidth["Хранилище"] = Math.Max(colWidth["Хранилище"],
result.IsInstalled ? $"{result.StoreLocation}\\{result.StoreName}".Length + 2 : 12);
}
var header = $"│ {"#".PadRight(colWidth["#"])} │ " +
$"{"Имя".PadRight(colWidth["Имя"])} │ " +
$"{"Отпечаток".PadRight(colWidth["Отпечаток"])} │ " +
$"{"Действителен до".PadRight(colWidth["Действителен до"])} │ " +
$"{"Статус".PadRight(colWidth["Статус"])} │ " +
$"{"Ключ".PadRight(colWidth["Ключ"])} │ " +
$"{"Цепочка".PadRight(colWidth["Цепочка"])} │ " +
$"{"Хранилище".PadRight(colWidth["Хранилище"])} │";
var separator = $"├{"".PadRight(colWidth["#"] + 1, '─')}┼{"".PadRight(colWidth["Имя"] + 1, '─')}┼{"".PadRight(colWidth["Отпечаток"] + 1, '─')}┼{"".PadRight(colWidth["Действителен до"] + 1, '─')}┼{"".PadRight(colWidth["Статус"] + 1, '─')}┼{"".PadRight(colWidth["Ключ"] + 1, '─')}┼{"".PadRight(colWidth["Цепочка"] + 1, '─')}┼{"".PadRight(colWidth["Хранилище"] + 1, '─')}┤";
var topBorder = $"┌{"".PadRight(colWidth["#"] + 1, '─')}┬{"".PadRight(colWidth["Имя"] + 1, '─')}┬{"".PadRight(colWidth["Отпечаток"] + 1, '─')}┬{"".PadRight(colWidth["Действителен до"] + 1, '─')}┬{"".PadRight(colWidth["Статус"] + 1, '─')}┬{"".PadRight(colWidth["Ключ"] + 1, '─')}┬{"".PadRight(colWidth["Цепочка"] + 1, '─')}┬{"".PadRight(colWidth["Хранилище"] + 1, '─')}┐";
var bottomBorder = $"└{"".PadRight(colWidth["#"] + 1, '─')}┴{"".PadRight(colWidth["Имя"] + 1, '─')}┴{"".PadRight(colWidth["Отпечаток"] + 1, '─')}┴{"".PadRight(colWidth["Действителен до"] + 1, '─')}┴{"".PadRight(colWidth["Статус"] + 1, '─')}┴{"".PadRight(colWidth["Ключ"] + 1, '─')}┴{"".PadRight(colWidth["Цепочка"] + 1, '─')}┴{"".PadRight(colWidth["Хранилище"] + 1, '─')}┘";
Console.WriteLine(topBorder);
Console.WriteLine(header);
Console.WriteLine(separator);
for (int i = 0; i < results.Count; i++)
{
var result = results[i];
var status = result.IsInstalled ? "✅ Уст." : "❌ Нет";
var hasKey = result.HasPrivateKey ? "✅ Есть" : "❌ Нет";
var chain = result.ChainValidationResult.IsValid ? "✅ Ок" : "⚠️ Пробл.";
var thumbprint = result.Thumbprint.Length > 14 ?
result.Thumbprint.Substring(0, 12) + "..." :
result.Thumbprint;
var store = result.IsInstalled ?
$"{result.StoreLocation}\\{result.StoreName}" :
"Не установлен";
if (!result.IsInstalled)
{
Console.ForegroundColor = ConsoleColor.Red;
}
else if (result.NotAfter < DateTime.Now)
{
Console.ForegroundColor = ConsoleColor.Yellow;
}
else if (!result.ChainValidationResult.IsValid)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
}
else
{
Console.ForegroundColor = ConsoleColor.Green;
}
var row = $"│ {(i + 1).ToString().PadRight(colWidth["#"])} │ " +
$"{result.FriendlyName.PadRight(colWidth["Имя"])} │ " +
$"{thumbprint.PadRight(colWidth["Отпечаток"])} │ " +
$"{result.NotAfter:dd.MM.yyyy}".PadRight(colWidth["Действителен до"]) + " │ " +
$"{status.PadRight(colWidth["Статус"])} │ " +
$"{hasKey.PadRight(colWidth["Ключ"])} │ " +
$"{chain.PadRight(colWidth["Цепочка"])} │ " +
$"{store.PadRight(colWidth["Хранилище"])} │";
Console.WriteLine(row);
Console.ResetColor();
}
Console.WriteLine(bottomBorder);
}
}