Httplistener с поддержкой HTTPS
Кажется, есть много запутанной, иногда противоречивой информации, касающейся возможности .NET HTTPListener HTTPS. Мое понимание таково:
Для одного кода С# требуется префикс https
(например, https://*:8443
), чтобы слушатель мог понять, что ему нужно обслуживать запросы SSL на этом порту.
Фактическое рукопожатие SSL происходит под прикрытием и обрабатывается http.sys
(похоронен где-то на машине Windows). Код С# не должен явно управлять рукопожатием SSL, потому что это происходит под прикрытием.
Нужно иметь "доверенный сертификат X.509" на машине httpListener
, и каким-то образом этот сертификат должен быть привязан к порту 8443 (в этом примере).
Правильно ли мое понимание выше? Если нет, пожалуйста, просветите меня.
Что касается сертификатов X.509, я понимаю следующее:
- Используйте
makecert
для создания сертификата X.509. Этот сертификат хранится в личном хранилище и должен быть перемещен в доверенное хранилище (именно здесь будет искать HTTP-слушатель). Кажется, я могу использовать certMgr
, чтобы выполнить движение, или я могу использовать mmc
, чтобы произвести движение. Кажется, существует более одного формата сертификата X.509 (DER
, Base64
, pks
, защищенный pswd, pks
закрытый и т.д.)... Есть ли предпочтительный формат, который я должен использовать?
Как только я получу сертификат в доверенное хранилище, мне нужно привязать его к порту TCP. Я нахожусь на Windows 7: я должен использовать httpcfg
или netsh
?
Ответы
Ответ 1
Я сделал кучу домашних заданий и получил эту работу. Шаги для добавления поддержки SSL для .NET HttpListener:
Обновите код приложения С#, включив в него префикс https
. Пример:
String[] prefixes = { "http://*:8089/","https://*:8443/" };
Это с точки зрения кода.
Что касается сертификатов, используйте командную консоль Windows SDK (также можно использовать командную консоль Visual Studio Professional)
Используйте makecert.exe
для создания центра сертификации. Пример:
makecert -n "CN=vMargeCA" -r -sv vMargeCA.pvk vMargeCA.cer
Используйте makecert.exe
для создания сертификата SSL
makecert -sk vMargeSignedByCA -iv vMargeCA.pvk -n "CN=vMargeSignedByCA" -ic vMargeCA.cer vMargeSignedByCA.cer -sr localmachine -ss My
Используйте MMC GUI для установки CA в хранилище Trusted Authority
- Используйте MMC GUI для установки SSL-сертификата в личном хранилище
Свяжите сертификат с IP address:port
и приложением. Пример:
netsh http add sslcert ipport=0.0.0.0:8443 certhash=585947f104b5bce53239f02d1c6fed06832f47dc appid={df8c8073-5a4b-4810-b469-5975a9c95230}
Certhash - это отпечаток вашего SSL-сертификата. Вы можете найти это используя mmc.
Appid находится в Visual Studio... обычно в файле Assembly.cs, найдите значение GUID.
Могут быть и другие способы выполнения вышесказанного, но это сработало для меня.
Ответ 2
Ниже подробно описаны шаги, которые я выполнил, чтобы настроить автономный сервер в Windows, используя OpenSSL для создания самозаверяющего сертификата для приложения С# HTTPListener
. Он содержит множество ссылок на случай, если вы захотите провести дальнейшие исследования.
Создайте автономный сервер в .NET через HttpListener
:
var prefixes = {"http://localhost:8080/app/root", "https://localhost:8443/app/root"};
var listener = new HttpListener();
foreach (string s in prefixes)
listener.Prefixes.Add(s);
listener.Start();
Создать самозаверяющий сертификат: *
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
, который запросит у вас значение каждого из полей сертификата в командной строке. В качестве общего имени введите имя домена (например, localhost
)
openssl pkcs12 -inkey bob_key.pem -in bob_cert.cert -export -out bob_pfx.pfx
, чтобы его можно было импортировать с помощью своего ключа на целевой компьютер.
* Для альтернативного использования makecert
см. собственный Уолтер ответ.
Откройте диспетчер сертификатов для локального компьютера. Когда вы запускаете certmgr.msc
, он открывает Диспетчер сертификатов для текущего пользователя, что здесь не то, что нам нужно. Вместо этого:
- Из административной командной строки на целевом компьютере запустите
mmc
- Нажмите Ctrl + M или нажмите File > Add/Remove Snap-in
- Выберите
Certificates
и нажмите Add >
- В появившемся диалоговом окне выберите
Computer Account
и нажмите Next
- Выберите
Local Computer
. Нажмите Finish, затем Okay
Импортируйте сертификат (pfx
) в Хранилище сертификатов Windows на целевом компьютере
- В ранее открытом окне
mmc
перейдите к Certificates (Local Computer) > Personal
- Щелкните правой кнопкой мыши
Personal
, затем нажмите All Tasks -> Import...
- На втором экране диалогового окна найдите и импортируйте свой сертификат. Вам нужно изменить фильтр типов файлов на
Personal Information Exchange
или All Files
, чтобы найти его
- На следующем экране введите пароль, выбранный на шаге 2.1, и обратите особое внимание на первый флажок. Это определяет, насколько надежно хранится ваш сертификат, а также насколько удобно его использовать
- На последнем экране выберите
Place all certificates in the following store
. Убедитесь, что написано Personal
, затем нажмите Finish
- Повторите описанную выше процедуру импорта для раздела сертификатов
Trusted Root Certification Authorities
.
Создайте ассоциации портов для вашего приложения. В Windows Vista и более поздних версиях используйте netsh
, как и я. (Для Windows XP и более ранних версий используйте httpcfg
)
В административной командной строке введите следующее, чтобы установить привязку SSL* к вашему приложению и соответствующий порт.
Примечание: Эту команду легко ошибиться, поскольку (в PowerShell) скобки необходимо экранировать. Будет работать следующая команда PowerShell:
netsh http add sslcert ipport=0.0.0.0:8443 '
certhash=110000000000003ed9cd0c315bbb6dc1c08da5e6 '
appid='{00112233-4455-6677-8899-AABBCCDDEEFF'}
Для cmd.exe
следует использовать следующее:
netsh http add sslcert ipport=0.0.0.0:8443 certhash=110000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}
- Параметр
ipport
приведет к привязке сертификата SSL к порту 8443
на каждом сетевом интерфейсе; для привязки к определенному интерфейсу (только) выберите IP-адрес, связанный с этим сетевым интерфейсом.
certhash
- это просто отпечаток сертификата с удаленными пробелами
appid
- это GUID, хранящийся в информации о сборке вашего приложения. (Примечание: механизм netsh
, очевидно, является интерфейсом COM, судя по этому вопросу и его ответам)
* Microsoft перенаправила ссылку привязки SSL с здесь на там.
Запустите свой веб-сервер, и все готово!
Ответ 3
Поскольку ваши собственные самоподписанные сертификаты в ответах не работали для меня, и поскольку в этом вопросе конкретно содержится призыв к созданию https-сервера HTTP.ListListener и запрашивается какие-либо советы/рекомендации, я хочу поделиться своим подходом. hostname, что-то вроде www.made-up.com, которое должно указывать на ваш WAN IP (например, спросите у своего поставщика хоста инструкции) и переместите его порт, например 443 на ваш локальный компьютер. Не забудьте открыть этот входящий порт 443 в своем брандмауэре вашей локальной машины.
Я использовал https://letsencrypt.org/. В Windows это не так просто, как на Linux, потому что нет официального сертификата ACME certbot для окон. Однако вы можете использовать https://github.com/Lone-Coder/letsencrypt-win-simple, из которых также существуют двоичные файлы. Однако "В настоящее время поддерживается только IIS". Но вы можете легко обмануть его, чтобы создать сертификат на вашем компьютере, чтобы вы могли приблизиться к своему httplistener по протоколу SSL:
- Установите IIS (через функции Windows в/из), создайте веб-сайт в IIS и назначьте имя хоста. Также создайте безопасный (443-портовый) веб-сайт.
- Run letencrypt-win-simple exe (я использовал версию 1.9.1). Ответьте на вопросы, чтобы они могли сгенерировать сертификат.
- После этого вы можете остановить IIS-сервер.
Я считаю, что вы должны принять к сведению задание обновления, поскольку я не уверен, что это произойдет через несколько месяцев (вам, вероятно, придется снова запустить IIS для обновления сертификата).
Ответ 4
Мы можем импортировать сертификаты, используя PowerShell и С# (ручные действия не требуются).
Для получения дополнительной информации см.: https://blog.davidchristiansen.com/2016/09/howto-create-self-signed-certificates-with-powershell/
Я использую этот код:
/// <summary>
/// Create and install a self-signed certificate for HTTPS use
/// </summary>
private static void CreateInstallCert(int expDate, string password, string issuedBy)
{
// Create/install certificate
using (var powerShell = System.Management.Automation.PowerShell.Create())
{
var notAfter = DateTime.Now.AddYears(expDate).ToLongDateString();
var assemPath = Assembly.GetCallingAssembly().Location;
var fileInfo = new FileInfo(assemPath);
var saveDir = Path.Combine(fileInfo.Directory.FullName, "CertDir");
if (!Directory.Exists(saveDir))
{
Directory.CreateDirectory(saveDir);
}
// This adds certificate to Personal and Intermediate Certification Authority
var rootAuthorityName = "My-RootAuthority";
var rootFriendlyName = "My Root Authority";
var rootAuthorityScript =
$"$rootAuthority = New-SelfSignedCertificate" +
$" -DnsName '{rootAuthorityName}'" +
$" -NotAfter '{notAfter}'" +
$" -CertStoreLocation cert:\\LocalMachine\\My" +
$" -FriendlyName '{rootFriendlyName}'" +
$" -KeyUsage DigitalSignature,CertSign";
powerShell.AddScript(rootAuthorityScript);
// Export CRT file
var rootAuthorityCrtPath = Path.Combine(saveDir, "MyRootAuthority.crt");
var exportAuthorityCrtScript =
$"$rootAuthorityPath = 'cert:\\localMachine\\my\\' + $rootAuthority.thumbprint;" +
$"Export-Certificate" +
$" -Cert $rootAuthorityPath" +
$" -FilePath {rootAuthorityCrtPath}";
powerShell.AddScript(exportAuthorityCrtScript);
// Export PFX file
var rootAuthorityPfxPath = Path.Combine(saveDir, "MyRootAuthority.pfx");
var exportAuthorityPfxScript =
$"$pwd = ConvertTo-SecureString -String '{password}' -Force -AsPlainText;" +
$"Export-PfxCertificate" +
$" -Cert $rootAuthorityPath" +
$" -FilePath '{rootAuthorityPfxPath}'" +
$" -Password $pwd";
powerShell.AddScript(exportAuthorityPfxScript);
// Create the self-signed certificate, signed using the above certificate
var gatewayAuthorityName = "My-Service";
var gatewayFriendlyName = "My Service";
var gatewayAuthorityScript =
$"$rootcert = ( Get-ChildItem -Path $rootAuthorityPath );" +
$"$gatewayCert = New-SelfSignedCertificate" +
$" -DnsName '{gatewayAuthorityName}'" +
$" -NotAfter '{notAfter}'" +
$" -certstorelocation cert:\\localmachine\\my" +
$" -Signer $rootcert" +
$" -FriendlyName '{gatewayFriendlyName}'" +
$" -KeyUsage KeyEncipherment,DigitalSignature";
powerShell.AddScript(gatewayAuthorityScript);
// Export new certificate public key as a CRT file
var myGatewayCrtPath = Path.Combine(saveDir, "MyGatewayAuthority.crt");
var exportCrtScript =
$"$gatewayCertPath = 'cert:\\localMachine\\my\\' + $gatewayCert.thumbprint;" +
$"Export-Certificate" +
$" -Cert $gatewayCertPath" +
$" -FilePath {myGatewayCrtPath}";
powerShell.AddScript(exportCrtScript);
// Export the new certificate as a PFX file
var myGatewayPfxPath = Path.Combine(saveDir, "MyGatewayAuthority.pfx");
var exportPfxScript =
$"Export-PfxCertificate" +
$" -Cert $gatewayCertPath" +
$" -FilePath {myGatewayPfxPath}" +
$" -Password $pwd"; // Use the previous password
powerShell.AddScript(exportPfxScript);
powerShell.Invoke();
}
}
Требуется PowerShell 4 или выше.
Ответ 5
@jpaugh: На самом деле это вопрос о вашем ответе. В ваших подробных шагах 3, 4, 5 вы упоминаете "локальный компьютер" и "целевой компьютер". Они оба одинаковые или разные машины? Я пытаюсь создать рабочий пример, имея клиентскую машину и сервер (слушатель). Все ваши шаги 3, 4, 5 выполнены на сервере? Спасибо!
Ответ 6
Вот полный рабочий код для HTTPListener на HTTPS (также работает в локальной сети).
Чтобы создать самоподписанный сертификат в С# с помощью Bouncy Castle и разрешить доступ к URL-адресу в локальной сети.
ПРИМЕЧАНИЕ. Не забудьте запустить с правами администратора.
Шаг 1. Установите Bouncy Castle Pacakge:
Install-Package BouncyCastle -Version 1.8.5
Шаг 2. Чтобы получить доступ к URL-адресу по локальной сети, нам нужно добавить правило брандмауэра с помощью Power Shell. Добавьте ссылку на System.Management.Automation.dll. Можно найти в GAC.
Шаг 3. Полный код
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace HTTPSListenerCode
{
class Program
{
static int _sslPort;
static Thread _serverThread;
static HttpListener _listener;
static void Main()
{
_sslPort = 34443;
string certificateSubjectName = "MyCertificate";
var cert = CreateInstallCert(_sslPort, certificateSubjectName, GetLocalIPAddress(), "*.domain.com");
InitializeHTTPListner();
string url = "https://localhost:" + _sslPort.ToString();
System.Diagnostics.Process.Start(url);
}
static void InitializeHTTPListner()
{
//Need to Firewall rule to access the IP in LAN
//Add refernce to C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
var powershell = PowerShell.Create();
var psCommand = $"New-NetFirewallRule -DisplayName \"My HTTP Listener Print Server\" -Direction Inbound -LocalPort {_sslPort} -Protocol TCP -Action Allow";
powershell.Commands.AddScript(psCommand);
powershell.Invoke();
_serverThread = new Thread(HTTPListen);
_serverThread.Start();
}
static void HTTPListen()
{
_listener = new HttpListener();
_listener.Prefixes.Add("https://*:" + _sslPort.ToString() + "/");
_listener.Start();
while (true)
{
try
{
IAsyncResult result = _listener.BeginGetContext(new AsyncCallback(HttpListenerCallback), _listener);
Console.WriteLine("Waiting for request to be processed asyncronously.");
result.AsyncWaitHandle.WaitOne(); //just needed to don't close this thread, you can do other work or run in a loop
Console.WriteLine("Request processed asyncronously.");
//HttpListenerContext context = _listener.GetContext();
//Process(context);
}
catch (Exception ex)
{
}
}
}
static void HttpListenerCallback(IAsyncResult result)
{
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
//Process(context);
var html = $"<html><body><h1>HTTP Listener is working</h1></body></html>";
byte[] bOutput2 = System.Text.Encoding.UTF8.GetBytes(html);
context.Response.ContentType = "text/html";
context.Response.ContentLength64 = bOutput2.Length;
Stream OutputStream2 = context.Response.OutputStream;
OutputStream2.Write(bOutput2, 0, bOutput2.Length);
OutputStream2.Close();
context.Response.StatusCode = (int)HttpStatusCode.OK;
}
static X509Certificate2 CreateInstallCert(int sslPort, string subjectName, string ipAddress, string domain)
{
X509Certificate2 cert = CheckAndGenerate(subjectName, ipAddress, domain);
if (cert == null)
{
throw new ArgumentNullException("Certificate");
}
var applicationId = ((GuidAttribute)typeof(Program).Assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;
var sslCert = ExecuteCommand("netsh http show sslcert 0.0.0.0:" + sslPort);
if (sslCert.IndexOf(cert.Thumbprint, StringComparison.OrdinalIgnoreCase) >= 0)
{
if (sslCert.IndexOf(applicationId, StringComparison.OrdinalIgnoreCase) >= 0)
{
return cert;
}
}
Console.WriteLine(ExecuteCommand("netsh http delete sslcert ipport=0.0.0.0:" + sslPort));
sslCert = ExecuteCommand("netsh http show sslcert 0.0.0.0:" + sslPort);
Console.WriteLine(sslCert);
if (sslCert.IndexOf(applicationId, StringComparison.OrdinalIgnoreCase) >= 0)
{
Console.WriteLine("This implies we can start running.");
Console.WriteLine(ExecuteCommand("netsh http delete sslcert ipport=0.0.0.0:" + sslPort));
}
Console.WriteLine(ExecuteCommand($"netsh http add sslcert ipport=0.0.0.0:{sslPort} certhash={cert.Thumbprint} appid={{{applicationId}}}"));
return cert;
}
static X509Certificate2 CheckAndGenerate(string subjectName, string ipAddress, string domain)
{
AsymmetricKeyParameter caPrivateKey = null;
string subjectCAName = subjectName + "CA";
var caCert = CheckIfCertificateExists(subjectCAName, StoreName.Root, StoreLocation.LocalMachine);
var clientCert = CheckIfCertificateExists(subjectName, StoreName.My, StoreLocation.LocalMachine);
if (caCert == null)
{
caCert = GenerateCACertificate("CN=" + subjectCAName, ref caPrivateKey);
addCertToStore(caCert, StoreName.Root, StoreLocation.LocalMachine);
if (clientCert == null)
{
clientCert = GenerateSelfSignedCertificate("CN=" + subjectName, "CN=" + subjectCAName, caPrivateKey, ipAddress, domain);
var p12 = clientCert.Export(X509ContentType.Pfx);
addCertToStore(new X509Certificate2(p12, (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet), StoreName.My, StoreLocation.LocalMachine);
addCertToStore(new X509Certificate2(p12, (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet), StoreName.Root, StoreLocation.LocalMachine);
}
}
return clientCert;
}
static X509Certificate2 CheckIfCertificateExists(string subjectName, StoreName storeName, StoreLocation storeLocation)
{
X509Store store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 certificate = null;
try
{
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, subjectName, false);
if (certificates != null && certificates.Count > 0)
{
///log.Info("CHECK for X509 Certificate in localmachine certificate store = OK");
certificate = certificates[0];
}
}
catch (Exception ex)
{
}
return certificate;
}
static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, string ipAddress, string domain)
{
const int keyStrength = 2048;
// Generating Random Numbers
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
// The Certificate Generator
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
// Serial Number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
// Signature Algorithm
const string signatureAlgorithm = "SHA256WithRSA";
certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
// Issuer and Subject Name
X509Name subjectDN = new X509Name(subjectName);
X509Name issuerDN = new X509Name(issuerName);
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
// Valid For
DateTime notBefore = DateTime.UtcNow.Date;
DateTime notAfter = notBefore.AddYears(2);
certificateGenerator.SetNotBefore(notBefore);
certificateGenerator.SetNotAfter(notAfter);
// Subject Public Key
AsymmetricCipherKeyPair subjectKeyPair;
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
var keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
// Generating the Certificate
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
//
List<GeneralName> altNames = new List<GeneralName>();
altNames.Add(new GeneralName(GeneralName.IPAddress, "127.0.0.1"));
altNames.Add(new GeneralName(GeneralName.IPAddress, ipAddress));
altNames.Add(new GeneralName(GeneralName.DnsName, domain));
altNames.Add(new GeneralName(GeneralName.DnsName, "localhost"));
GeneralNames subjectAltNames = GeneralNames.GetInstance(new DerSequence((GeneralName[])altNames.ToArray()));
certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltNames);
//
// selfsign certificate
Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerPrivKey, random);
// correcponding private key
PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
// merge into X509Certificate2
X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());
if (seq.Count != 9)
{
//throw new PemException("malformed sequence in RSA private key");
}
RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);
RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);
x509.PrivateKey = ToDotNetKey(rsaparams); //x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
return x509;
}
static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
{
var cspParams = new CspParameters
{
KeyContainerName = Guid.NewGuid().ToString(),
KeyNumber = (int)KeyNumber.Exchange,
Flags = CspProviderFlags.UseMachineKeyStore
};
var rsaProvider = new RSACryptoServiceProvider(cspParams);
var parameters = new RSAParameters
{
Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
P = privateKey.P.ToByteArrayUnsigned(),
Q = privateKey.Q.ToByteArrayUnsigned(),
DP = privateKey.DP.ToByteArrayUnsigned(),
DQ = privateKey.DQ.ToByteArrayUnsigned(),
InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
D = privateKey.Exponent.ToByteArrayUnsigned(),
Exponent = privateKey.PublicExponent.ToByteArrayUnsigned()
};
rsaProvider.ImportParameters(parameters);
return rsaProvider;
}
static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
{
const int keyStrength = 2048;
// Generating Random Numbers
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
// The Certificate Generator
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
// Serial Number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
// Signature Algorithm
const string signatureAlgorithm = "SHA256WithRSA";
certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
// Issuer and Subject Name
X509Name subjectDN = new X509Name(subjectName);
X509Name issuerDN = subjectDN;
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
// Valid For
DateTime notBefore = DateTime.UtcNow.Date;
DateTime notAfter = notBefore.AddYears(2);
certificateGenerator.SetNotBefore(notBefore);
certificateGenerator.SetNotAfter(notAfter);
// Subject Public Key
AsymmetricCipherKeyPair subjectKeyPair;
KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
// Generating the Certificate
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
// selfsign certificate
Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);
X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
CaPrivateKey = issuerKeyPair.Private;
return x509;
//return issuerKeyPair.Private;
}
static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
{
bool bRet = false;
try
{
X509Store store = new X509Store(st, sl);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
}
catch
{
}
return bRet;
}
static string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return "127.0.0.1";
//throw new Exception("No network adapters with an IPv4 address in the system!");
}
static string ExecuteCommand(string action)
{
StringBuilder stringBuilder = new StringBuilder();
using (Process process = new Process
{
StartInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Normal,
FileName = "cmd.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = "/c " + action
}
})
{
Console.WriteLine("Executing Command:");
Console.WriteLine(action);
process.Start();
while (!process.StandardOutput.EndOfStream)
{
stringBuilder.AppendLine(process.StandardOutput.ReadLine());
}
process.Close();
}
return stringBuilder.ToString();
}
}
}