문제

통신을 위해 TCP/IP 소켓을 사용하는 다양한 프로세스간에 안전한 커뮤니케이션을 제공해야합니다. 인증과 암호화를 원합니다. 휠을 재발 명하지 않고 SSL과 SSLStream 클래스 및 자체 서명 된 인증서를 사용하고 싶습니다. 내가하고 싶은 것은 로컬 응용 프로그램의 알려진 사본에 대해 원격 프로세스의 인증서를 검증하는 것입니다. (인증서를 수동으로 복사 할 계획이므로 인증 기관이 필요하지 않습니다).

이를 위해 응용 프로그램이 처음 실행될 때 새 인증을 자동으로 생성 할 수 있기를 원합니다. makecert.exe 외에도 마찬가지입니다 이 링크 자체 서명 된 인증서를 자동으로 생성하는 방법을 보여 주므로 시작입니다.

SSLStream의 authenticateasserver 및 authenticateasclient 방법을 보았습니다. 검증을 위해 콜백을 제공 할 수 있으므로 가능해 보입니다. 그러나 이제 나는 그것의 세부 사항에 들어서서, 나는 이것을 할 수 있다고 생각하지 않습니다.

내가 올바른 방향으로 가고 있습니까? 더 나은 대안이 있습니까? 누구든지 이전에 이와 같은 일을 한 사람이 있습니까 (기본적으로 클라이언트 서버보다는 피어 투 피어 SSL)?

도움이 되었습니까?

해결책

1 단계: 자체 서명 된 인증서 생성 :

  • 나는 그것을 다운로드했다 인증서 .CS 클래스 Doug Cook에 의해 게시되었습니다
  • 이 코드를 사용하여 .pfx 인증서 파일을 생성했습니다.

    byte[] c = Certificate.CreateSelfSignCertificatePfx(
            "CN=yourhostname.com", //host name
            DateTime.Parse("2000-01-01"), //not valid before
            DateTime.Parse("2010-01-01"), //not valid after
            "mypassword"); //password to encrypt key file
    
        using (BinaryWriter binWriter = new BinaryWriter(
            File.Open(@"testcert.pfx", FileMode.Create)))
        {
            binWriter.Write(c);
        }
    

2 단계: 인증서로드

    X509Certificate cert = new X509Certificate2(
                            @"testcert.pfx", 
                            "mypassword");

3 단계 : : 그것을 합친다

  • 나는 그것을 기반으로한다 이 매우 간단한 sslstream 예제
  • SSLProtocoltype 열거에 대한 컴파일 타임 오류가 발생합니다. sslprotocoltype.default에서 sslprotocols.default로 변경하십시오
  • 더 이상 사용되지 않은 기능에 대한 3 가지 경고가있었습니다. 나는 그들 모두를 제안 된 교체품으로 교체했습니다.
  • 서버 프로그램 에서이 줄을 교체했습니다 .CS 파일은 2 단계에서 라인으로 대체했습니다.

    x509certificate cert = getervercert ();

  • Client Program.cs 파일에서 ServerName = YourHostName.com을 설정하고 인증서의 이름과 일치해야합니다)

  • client program.cs에서 sslpolicyerrors에는 remotecertificatechainerrors가 포함되어 있기 때문에 CertificateValidationCallback 함수가 실패합니다. 당신이 조금 더 깊이 파고 들면, 이것은 인증서에 서명 한 발행 기관이 신뢰할 수있는 루트가 아니기 때문입니다.
  • 사용자 가져 오기 인증서를 루트 스토어 등으로 가져 오지 않으려 고하지 않으므로 특별한 경우를 만들었고 해당 증명서를 확인합니다. getPublicKeyString ()은 파일에있는 공개 키와 같습니다. 그 서버의 경우. 그것이 일치하면, 나는 그 기능에서 true를 반환합니다. 그것은 효과가있는 것 같습니다.

Step 4: 클라이언트 인증

내 클라이언트가 인증하는 방법은 다음과 같습니다 (서버와 약간 다릅니다).

TcpClient client = new TcpClient();
client.Connect(hostName, port);

SslStream sslStream = new SslStream(client.GetStream(), false,
    new RemoteCertificateValidationCallback(CertificateValidationCallback),
    new LocalCertificateSelectionCallback(CertificateSelectionCallback));

bool authenticationPassed = true;
try
{
    string serverName = System.Environment.MachineName;

    X509Certificate cert = GetServerCert(SERVER_CERT_FILENAME, SERVER_CERT_PASSWORD);
    X509CertificateCollection certs = new X509CertificateCollection();
    certs.Add(cert);

    sslStream.AuthenticateAsClient(
        serverName,
        certs,
        SslProtocols.Default,
        false); // check cert revokation
}
catch (AuthenticationException)
{
    authenticationPassed = false;
}
if (authenticationPassed)
{
    //do stuff
}

CertificateValidationCallback은 서버 케이스와 동일하지만 AuthenticateAsclient가 하나의 인증서가 아니라 인증서 모음을 어떻게 취하는지 주목하십시오. 따라서 LocalCertificatesElectionCallback을 추가해야합니다 (이 경우 클라이언트 인증서가 하나만 있으므로 컬렉션에서 첫 번째 클라이언트를 반환합니다).

static X509Certificate CertificateSelectionCallback(object sender,
    string targetHost,
    X509CertificateCollection localCertificates,
    X509Certificate remoteCertificate,
    string[] acceptableIssuers)
{
    return localCertificates[0];
}

다른 팁

이 예제 샘플 비동기 SSLStream 클라이언트/서버 구현을 볼 수 있습니다.http://blogs.msdn.com/joncole/archive/2007/06/13/sample-asynchronous-sslstream-mient-server-meplementation.aspx

인증서가 올바르게 생성되지 않으면 예외를 얻을 수 있습니다. 서버 모드 SSL은 관련 개인 키와 함께 인증서를 사용해야합니다.

기본 인증서 예

makecert -sr localmachine -ss my -n cn = test -sky exchange -sk 123456

또는

외부 파일로

makecert -sr localmachine -ss my -n cn = test -sky exchange -sk 123456 c : test.cer

인증서 생성 도구 (makecert.exe)
http://msdn.microsoft.com/en-us/library/bfsktky3%28vs.80%29.aspx

당신이 제안하는 것은 인증서를 생성하기 위해 콜백이 호출 될 때까지 기다리는 것처럼 들린다는 점을 제외하고는 나에게 괜찮습니다. 나는 그것이 날아갈 것이라고 생각하지 않습니다. Afaik, 호출 할 때 유효한 인증서를 제공해야합니다. AuthenticateAsX.

그러나이 클래스는 우선적입니다. 따라서 이론적으로, 인증서를 생성 해야하는지 확인하기 위해 첫 번째 검사를받은 파생 클래스를 만들 수 있습니다. 필요한 경우 생성 한 다음 부모를 호출 할 수 있습니다. AuthenticateAsX 방법.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top