HTTPS를 지원하는 Httplistener
.NET HTTPListener HTTPS를 지원하는 것과 관련하여 혼란스럽고 때로는 충돌하는 정보가 많이있는 것 같습니다. 내 이해는 다음과 같습니다.
수신기가이 포트에서 SSL 요청을 처리해야한다는 것을 이해하려면 C # 코드에
https접두사 (예https://*:8443:)가 필요합니다.실제 SSL 핸드 셰이크는 내부적으로 발생
http.sys하며 Windows 시스템 어딘가에 묻혀 있습니다. C # 코드는 SSL 핸드 셰이크를 내부에서 발생하므로 명시 적으로 관리 할 필요가 없습니다.하나는
httpListener컴퓨터 에 "X.509 신뢰할 수있는 인증서"가 있어야 하고 어떻게 든 해당 인증서를 포트 8443 (이 예에서)에 바인딩해야합니다.
위의 이해가 맞습니까? 그렇지 않다면 저를 교육하십시오.
X.509 인증서와 관련하여 내 이해는 다음과 같습니다.
makecertX.509 인증서를 만드는 데 사용 합니다. 이 인증서는 개인 저장소에 저장되고 신뢰할 수있는 저장소 (HTTP 리스너가 표시되는 위치)로 이동해야합니다. 내가 사용할 수있는 것 같다certMgr이동을 수행하기 위해, 또는 내가 사용할 수있는mmc이동에 영향을 할 수 있습니다. 그것은 하나 이상의 X.509 인증서 형식이 (것 같다DER,Base64,pks,, 보호 PSWDpks내가 사용해야 원하는 형식이 있는가 ..., 개인 등.)?
인증서를 신뢰할 수있는 저장소로 가져 오면이를 TCP 포트에 바인딩해야합니다. 나는 윈도우 7에 오전 : 나는 사용해야 httpcfg나 netsh?
나는 많은 숙제를했고이 일을 해냈다. .NET HttpListener에 대한 SSL 지원을 추가하는 단계는 다음과 같습니다.
https접두사 를 포함하도록 C # 애플리케이션 코드를 업데이트 합니다. 예:String[] prefixes = { "http://*:8089/","https://*:8443/" };그것이 코드 측면에서 나온 것입니다.
인증서 측면의 경우 Windows SDK 명령 콘솔 사용 (Visual Studio Professional 명령 콘솔도 사용할 수 있음)
makecert.exe인증 기관을 만드는 데 사용 합니다. 예:makecert -n "CN=vMargeCA" -r -sv vMargeCA.pvk vMargeCA.cermakecert.exeSSL 인증서를 만드는 데 사용makecert -sk vMargeSignedByCA -iv vMargeCA.pvk -n "CN=vMargeSignedByCA" -ic vMargeCA.cer vMargeSignedByCA.cer -sr localmachine -ss MyMMC GUI를 사용하여 Trusted Authority 저장소에 CA 설치
- 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 값을 찾습니다.
위의 작업을 수행하는 다른 방법이있을 수 있지만 이것은 저에게 효과적이었습니다.
다음은 OpenSSL을 사용하여 C # HTTPListener애플리케이션에 대한 자체 서명 된 인증서를 생성하여 Windows에서 독립 실행 형 서버를 설정하기 위해 수행 한 단계 입니다. 추가 조사를 원할 경우를 위해 많은 링크가 포함되어 있습니다.
다음을 통해 .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은 Walter의 답변을 참조하십시오 .로컬 컴퓨터 용 인증서 관리자를 엽니 다. 를 실행
certmgr.msc하면 현재 사용자에 대한 인증서 관리자 가 열리지 만 여기서 원하는 것은 아닙니다. 대신 :- 대상 머신의 관리 명령 프롬프트에서 다음을 실행하십시오.
mmc - 를 누르 거나 클릭Ctrl + MFile > 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 바인딩 * 및 적절한 포트를 설정합니다. NB : 이 명령은 (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 인터페이스입니다. )
- 이
웹 서버를 시작하십시오.
답변에서 자체 서명 된 인증서를 만드는 것이 저에게 효과가 없었고 질문이 구체적으로 .net HTTPListener https를 사용할 수 있도록 만들고 팁 / 조언을 요청함에 따라 제 접근 방식을 공유하고 싶습니다. www.made-up.com과 같이 WAN IP를 가리키고 (예 : 호스트 공급자에게 지침 요청) 해당 포트 (예 : 443)를 로컬 컴퓨터로 전달해야합니다. 방화벽에서 해당 인바운드 443 포트를 여는 것을 잊지 마십시오. 로컬 컴퓨터.
https://letsencrypt.org/ 사용했습니다 . Windows 용 공식 certbot ACME 클라이언트가 없기 때문에 Windows에서는 Linux처럼 쉽지 않습니다. 그러나 https://github.com/Lone-Coder/letsencrypt-win-simple 을 사용할 수 있으며이 중 바이너리도 있습니다. 그러나 "현재 IIS 만 지원됩니다". 그러나 SSL 방식으로 httplistener에 접근 할 수 있도록 컴퓨터에 인증서를 생성하도록 쉽게 속일 수 있습니다.
- Windows 기능을 통해 IIS를 설치하고 IIS 내에 웹 사이트를 만들고 호스트 이름을 할당합니다. 또한 보안 (443 포트) 웹 사이트를 만드십시오.
- letsencrypt-win-simple exe를 실행합니다 (버전 1.9.1 사용). 인증서를 생성 할 수 있도록 질문에 답하십시오.
- 그 후에 IIS 서버를 중지 할 수 있습니다.
생성 된 새로 고침 작업을 기록해 두어야한다고 생각합니다. 몇 달 후에 성공할지 확신 할 수 없기 때문입니다 (인증서를 갱신하려면 IIS를 다시 시작해야합니다).
PowerShell 및 C #을 사용하여 인증서를 가져올 수 있습니다 (수동 단계 필요 없음).
자세한 내용은 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 이상이 필요합니다.
다음은 HTTPS의 HTTPListener에 대한 전체 작동 코드입니다 (LAN에서도 작동 함). Bouncy Castle을 사용하여 C #에서 자체 서명 된 인증서를 생성하고 LAN에서 URL에 액세스하도록 허용합니다.
참고 : 관리자로 실행하는 것을 잊지 마십시오.
1 단계 : Bouncy Castle Pacakge 설치 :
Install-Package BouncyCastle -Version 1.8.5
2 단계 : LAN을 통해 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();
}
}
}
참고 URL : https://stackoverflow.com/questions/11403333/httplistener-with-https-support
'Nice programing' 카테고리의 다른 글
| matplotlib를 사용하여 모든 서브 플롯의 기본 색상주기를 설정하는 방법은 무엇입니까? (0) | 2020.12.11 |
|---|---|
| 설정이 다른 두 파일에 로깅 (0) | 2020.12.11 |
| 번 들러는 보석을 어디에 보관하나요? (0) | 2020.12.11 |
| 와일드 카드가 일치하는 파일 찾기 (0) | 2020.12.11 |
| 어떻게 든 Swift에서 NSURLSession을 통해 동기 HTTP 요청을 할 수 있습니까? (0) | 2020.12.11 |