Bankmail: spam van je bank

Door CodeCaster op woensdag 10 juli 2013 23:30 - Reacties (28)
Categorie: -, Views: 5.002

Al enige jaren heeft mijn favoriete bank, ABN AMRO, zoiets als bankmail:


Lees verder »

Windows 8 AppRace-inzending: Photostream

Door CodeCaster op zaterdag 05 januari 2013 18:30 - Reacties (16)
Categorie: Tech, Views: 3.902

Morgen is de laatste dag dat je je app kunt aanmelden voor de AppRace die Tweakers en Microsoft organiseren. Bij deze AppRace werden ontwikkelaars uitgedaagd om een Windows 8-app te bouwen, met kans op leuke prijzen. Ik heb ook meegedaan.


Lees verder »

Gedeelde directory voor NuGet-packages en automatisch packages downloaden

Door CodeCaster op zondag 18 november 2012 23:15 - Reageren is niet meer mogelijk
Categorie: Tech, Views: 2.566

De immer populaire uitbreiding van Visual Studio, NuGet genaamd, laat de developer eenvoudig packages downloaden vanuit zijn ontwikkelomgeving. Deze packages bevatten bekende en minder bekende libraries, zoals log4net, jQuery en Entity Framework.


Lees verder »

WCF: Beveiliging middels certificaten

Door CodeCaster op woensdag 24 oktober 2012 22:50 - Reacties (1)
Categorie: Tech, Views: 2.683

Een jaar geleden schreef ik voor het eerst iets over WCF. Een samenvatting: met Windows Communication Foundation, een onderdeel van het .NET-Framework, kun je op een uiterst eenvoudige wijze services creŰren en consumeren. Interoperabiliteit is hierbij het sleutelwoord; middels diverse zogeheten bindings kun je over verschillende transportlagen (TCP, HTTP(S), named pipes) in verschillende formaten (bijvoorbeeld SOAP, MSMQ of binair) berichten versturen. Deze berichten worden vanuit de code opgebouwd, waarbij WCF aan de client- maar ook aan de servicekant in de aflevering en ontvangst van deze berichten kan voorzien.

Beveiliging
Wanneer een WCF-service via een BasicHttpBinding of WsHttpBinding wordt gepubliceerd, wordt het berichtverkeer standaard in platte tekst over de lijn gestuurd, waardoor het dus leesbaar is voor iedereen die het netwerkverkeer kan onderscheppen. Daarnaast is bij beide bindingen geen bewijs dat de afzender is wie hij zegt dat hij is. Voor een via internet (of zelfs intranet) toegankelijke service is het dus erg verstandig om beveiliging toe te passen.

WCF is standaard al uitgerust met ondersteuning voor een hele rits veiligheidsmaatregelen. Zo is de WsHttpBinding uitgerust met WS-Security, zodat de inhoud van de berichten (maar niet het HTTP-verkeer zelf) wordt versleuteld. Met WS-Security kan een bericht ook worden voorzien van credentials, zodat de service de afzender kan controleren.

Zodra gevoelige informatie wordt uitgewisseld tussen client en service (zoals wachtwoorden, persoonsgegevens of betalingsinformatie), kan het niet de bedoeling zijn dat het transport niet versleuteld is. Voor de Basic- en WsHttpBinding valt deze keuze al snel op het gebruiken van HTTP Transport Security.

Certificaten
Om HTTP-verkeer te versleutelen, wordt gebruikgemaakt van certificaten. Een X.509-certificaat bevat onder andere gegevens waarmee een host ge´dentificeerd kan worden en sleutels waarmee verkeer ver- en ontsleuteld en ondertekend kan worden. Ook kunnen clients zich authenticeren met een clientcertificaat.

Afwegingen
De makkelijkste manier om een WCF-service op een beveiligde HTTP-verbinding te publiceren is door een site in Internet Information Services (IIS) aan te maken en deze bij de bindings aan een SSL-certificaat te koppelen. Bij deze instellingen regelt IIS alle communicatie met de client, waarin wordt bepaald dat deze beveiligd moet zijn zonder dat dit in de service(host) geprogrammeerd hoeft te worden.

Een andere optie is beveiligde self-hosting, waarbij middels de tool httpcfg het certificaat aan de gewenste TCP-poort wordt gekoppeld. Dit kost dus iets meer moeite dan het hosten in IIS, maar biedt onder andere wel het voordeel dat het op machines gehost kan worden die niet over IIS beschikken.

Certificaten maken
Om certificaten te genereren kun je de tool makecert gebruiken. Deze zijn om verschillende redenen meestal niet geschikt om in productie te gebruiken, maar uitstekend geschikt om tijdens de ontwikkeling en het testen te gebruiken.

Het programma makecert.exe wordt standaard in de map C:\Program Files (x86)\Microsoft SDKs\Windows\[versie\]\Bin ge´nstalleerd, een pad dat standaard in de %PATH%-variabele staat van de Visual Studio Command prompt, waardoor je het vanuit iedere directory kunt starten.

Een Certificate Authority aanmaken, opslaan en importeren in de Trusted Root Authority-store doe je met het volgende commando (dat ÚÚn regel telt, het is slechts opgesplitst ter verduidelijking):
makecert -n "CN=CodeCasterRoot" -sv CodeCasterRoot.pvk 
         -sr localmachine -ss root -r CodeCasterRoot.cer


Hierbij wordt eerst gevraagd om een wachtwoord waarmee het .pvk-bestand, dat de private keys gaat bevatten, versleuteld wordt. Vervolgens moet dit wachtwoord weer worden ingetikt, zodat het bestand gebruikt kan worden om het certificaat te genereren. Hierna wordt het certificaat ge´mporteerd in de Trusted Root Authority-store.

De private key-file en het wachtwoord moeten veilig worden opgeborgen, omdat op basis daarvan nieuwe certificaten kunnen worden uitgegeven die, door de chain of trust, automatisch vertrouwd worden door machines die het rootcertificaat vertrouwen. En daarom hebben we officiŰle certificaatinstanties. Dit certificaat moet in ieder geval op de webserver worden ge´mporteerd, zodat het mogelijk wordt om certificaten op basis van het rootcertiticaat in IIS te kunnen gebruiken om SSL toe te passen op een website. Het is ook mogelijk de certificaten op een andere machine aan te maken; dan kunnen de laatste twee argumenten van het makecert-commando worden weggelaten (-sr localmachine -ss root) en moet het .cer-bestand middels de MMC op de webserver worden ge´mporteerd in de Trusted Root Authority-store die zich in de 'locale machine'-store bevindt.

Op basis van het rootcertificaat kan nu een servercertificaat worden gemaakt. Wanneer er op de webserver wordt gewerkt, is dit commando het eenvoudigst en het veiligst:
makecert -n "CN=services.contoso.org" -iv CodeCasterRoot.pvk 
         -ic CodeCasterRoot.cer -a sha1 -sky exchange -sr localmachine -ss my

Hierdoor wordt het certificaat in de MMC ge´nstalleerd, terwijl de private keys niet exporteerbaar zijn. Als je de eigenschappen van het certificaat bekijkt, zie je dat het vertrouwd wordt:
Certificate chain of trust


Wanneer het certificaat op een andere machine wordt aangemaakt, zijn er twee manieren om het certificaat importeerbaar te maken mŔt private keys. De makkelijkste wijze is om het certificaat met exporteerbare sleutels direct te importeren in de store van de computer waarop je ze aanmaakt:
makecert -n "CN=services.contoso.org" -iv CodeCasterRoot.pvk 
         -ic CodeCasterRoot.cer -a sha1 -sky exchange -sr localmachine -ss my -pe


Hierna kun je een .pxf-bestand exporteren vanuit de MMC, door te rechtsklikken op het certificaat en het met private keys te exporteren. Wederom wordt gevraagd om een wachtwoord, waarmee het .pfx-bestand wordt versleuteld en dat weer nodig is om het certificaat op de doelmachine te importeren.

Als er geen Administrator-rechten zijn op de machine waarop het certificaat wordt aangemaakt, kan het certificaat niet worden ge´mporteerd in de store, waardoor er ook geen .pfx kan worden geŰxporteerd. Gelukkig kun je zelf een .pfx maken van een .pvk- en een .cer-bestand. Hiervoor is de commandlinetool pvk2pfx.exe, eveneens meegeleverd met de Windows SDK die wordt ge´nstalleerd tijdens de installatie van Visual Studio.

Eerst dienen de .cer en .pvk te worden aangemaakt:
makecert -n "CN=services.contoso.org" -sv ConsosoServer.pvk -iv CodeCasterRoot.pvk
         -ic CodeCasterRoot.cer -a sha1 -sky exchange ContosoServer.cer


Daarna kan een .pfx worden gemaakt:
pvk2pfx -spc ContosoServer.cer -pvk ConsosoServer.pvk -pfx ContosoServer.pfx


Deze .pfx kan nu op de webserver worden ge´mporteerd in de MMC, waarna het in IIS mogelijk wordt om een https-binding aan te maken die gebruik maakt van dit laatste certificaat.


Certificaat instellen in IIS
Om SSL toe te passen op een site, ga je in de IIS Manager naar de site die het betreft en klik je op Bindingen (of op Bindings, maar de Nederlandstalige versie van Windows was goedkoper) bij een bestaande site, of maak je een nieuwe site aan. In beide gevallen kun je een binding toevoegen, waarbij je https als protocol kiest en het zojuist aangemaakte certificaat selecteert.
IIS Add Web Site SSL

Deze site kan, na het aanmaken, via de opgegeven poort over een versleutelde verbinding worden benaderd.

Clients
Wanneer deze echter met een browser anders dan een op de server wordt bezocht (de server vertrouwt momenteel immers als enige computer op de wereld het root-certificaat), verschijnt een beveiligingsmelding:
Untrusted Root


Certificaten die op basis van deze authority worden gegenereerd, worden door de client geweigerd omdat het door een niet-vertrouwde instantie is uitgegeven. De eenvoudigste manier om dit op te lossen is het importeren van het root-certificaat-bestand CodeCasterRootCA.cer als Trusted Root Authority op de client,, wederom via de MMC.

Het is ook mogelijk om direct een self-signed certificaat aan te maken (middels de schakeloptie -r), waardoor de chain of trust buitenspel wordt gezet omdat het certificaat zijn eigen rootcertificaat is. Ieder certificaat dat gebruikt moet worden, dient bij deze werkwijze in de Trusted Root Authorities-store geplaatst te worden. Door echter gebruik te maken van ÚÚn root-certificaat dat de client vertrouwt worden nieuwe certificaten van dezelfde uitgever die gebaseerd zijn op dat rootcertificaat automatisch goedgekeurd. Zo hoeft niet ieder certificaat afzonderlijk te worden toegevoegd, wanneer bijvoorbeeld meerdere certificaten van dezelfde leverancier verwacht worden. Voor in de testomgeving.

Service beveiligen
Met de aangemaakte certificaten een service beveiligen is eenvoudig te doen. Op de site in IIS draait een eenvoudige service:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace CodeCaster.Services
{
    [ServiceContract]
    public interface IEchoService
    {
        [OperationContract]
        String Echo(String toEcho);
    }

    public class EchoService : IEchoService
    {
        public String Echo(String toEcho)
        {
            return "Echo: " + toEcho;
        }
    }
}


Deze service draait in de ContosoServices-site binnen zijn eigen directory, die EchoService heet. Van deze directory moet een 'applicatie' (application) worden gemaakt, anders krijg je bij het bezoeken van de service-URL de foutmelding "The type '<JouwService>', provided as the Service attribute value in the ServiceHost directive could not be found." (lang leve unlocalize.com). Of de DLL die de serviceklasse bevat mist.

Een applicatie maken van een directory is eenvoudig realiseren door in de IIS Manager te rechtsklikken op de betreffende directory en te kiezen voor 'Convert to Application'. Een applicatie zoekt, in tegenstelling tot code die eenvoudigweg in een directory staat, niet hoger (maar wel dieper) dan zijn eigen root-directory voor configuratie- en binaire bestanden, kan in zijn eigen application pool worden gedraaid en krijgt een eigen worker-proces toegewezen. Zo kun je applicaties binnen dezelfde site van elkaar isoleren.

Deze service bevat echter nog de standaardconfiguratie die met een WCF Service Library-project meekomt, dus is nog niet op de hoogte van het feit dat 'ie achter een beveiligde verbinding gehost wordt. Als je de een aanvraag doet naar de service op het https-adres (en dat kan ook een GET-aanvraag om metadata zijn, dus ook bij het met de browser bezoeken van de service-URL), wordt de foutmelding "Could not find a base address that matches scheme http for the endpoint with binding WSHttpBinding. Registered base address schemes are [https]." getoond. Dit wordt veroorzaakt doordat de binding van het metadata-endpoint nog op Http staat en omdat de securitymode van de WSHttpBinding nog niet op Transport staat.

Helaas krijgt de service van IIS niet door dat 'ie op de hostname van het certificaat draait, waardoor je de absolute URL zou moeten plaatsen bij <endpoint address="..." /> teneinde de metadata te kunnen publiceren. Wanneer je dit niet doet, zal de service de hostname van de machine waarop hij draait als adres aannemen, waardoor niet alleen de metadata onjuist gegenereerd wordt, maar zelfs "400 Bad Request"-responses kunnen worden gegooid: de service denkt dan immers dat hij helemaal geen "services.contoso.org" heet, maar "hostname", en zal daarom op basis van de verkeerde host- of SOAP-Action-header zo'n 400-, of een "404 Not Found"-foutmelding retourneren. Om aan zo min mogelijk configuratie te hoeven doen, is het natuurlijk niet handig om met hardcoded paden te werken. Die bepalen we immers al via het de mappenstructuur op het bestandssysteem en middels sitebindingen en -namen IIS.

Waar voorheen trucs uitgehaald moesten worden om IIS toch de hostname te laten herkennen, heeft WCF sinds .NET 4 een nieuw configuratie-item: het plaatsen van het elemenent <useRequestHeadersForMetadataAddress /> onder het behaviour van de service zorgt ervoor dat deze zich met de opgevraagde hostname (die de HTTP-client immers in ieder verzoek verplicht meestuurt) identificeert.

De system.serviceModel-sectie van de Web.config moet minstens de volgende configuratie bevatten om, inclusief metadata, over HTTPS te werken:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<system.serviceModel>
  <services>
    <service name="CodeCaster.Services.EchoService">
      <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpServerCert" contract="CodeCaster.Services.IEchoService">
      </endpoint>
      <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <useRequestHeadersForMetadataAddress />
        <serviceDebug includeExceptionDetailInFaults="True" />
        <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="wsHttpServerCert">
        <security mode="Transport">
          <transport clientCredentialType="None" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
</system.serviceModel>


Client
Als nu een Service Reference wordt aangemaakt naar de URL https://services.contoso.org:9001/
EchoService/EchoService.svc
, wordt een client gegenereerd die gebruikmaakt van de volgende configuratie:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IEchoService">
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://services.contoso.org:9001/EchoService/EchoService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEchoService"
        contract="EchoServiceReference.IEchoService" name="WSHttpBinding_IEchoService">
        <identity>
          <dns value="services.contoso.org" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>


VoilÓ, we hebben een beveiligde verbinding. Nu weten we echter nog niet wie de client is en of het bericht wel te vertrouwen is, maar dat bewaar ik voor een volgend blog.



http://codecaster.nl/got/rmb/star1.pnghttp://codecaster.nl/got/rmb/star2.pnghttp://codecaster.nl/got/rmb/star3.pnghttp://codecaster.nl/got/rmb/star4.pnghttp://codecaster.nl/got/rmb/star5.pnghttp://codecaster.nl/got/rmb/stats.gif

Sockets en protocollen: berichten uitwisselen. Met bytes.

Door CodeCaster op dinsdag 14 augustus 2012 10:00 - Reacties (11)
Categorie: Tech, Views: 4.414

English version

Wanneer twee applicaties over het netwerk of over internet met elkaar willen communiceren, wordt al snel gebruikgemaakt van netwerksockets. Deze sockets zijn een door tegenwoordig vrijwel ieder besturingssysteem aangeboden API, waarmee je de netwerkstack van het OS gemakkelijk kunt aanspreken om data over het lokale netwerk of het internet te kunnen versturen naar andere computers.


Lees verder »