Compare commits

...

No commits in common. '93367042b937cd2df88d66d4d3e0e22149206b46' and '517e8092e8e29c22f2fb07d266872af7c86c88cb' have entirely different histories.

  1. 23
      bonus.html
  2. 217
      certificaten.html
  3. 460
      encryptie.html
  4. 53
      letsencrypt.html
  5. 575
      oauth.html
  6. 5
      sql.html
  7. 4
      static/css/style.css
  8. 2
      static/js/quiz.js

@ -1,23 +0,0 @@
{% extends "base.html" %}
{% block content %}
<h1>Bonus</h1>
<div class="question">
<span class="question-string">Geef een beveiligingsprobleem aan met deze website (<a href="https://github.com/Avans/Security-Quiz">source</a>)</span>
<div class="points"><span class="question-points">0</span> punten (je naam vereeuwigd op deze website als hacker)</div>
<textarea class="question-input" name="answer_bonus_fix_this_site">{{answers.answer_bonus_fix_this_site.string}}</textarea>
</div>
<div class="alert alert-warning">Het daadwerkelijk uitvoeren van dergelijke hacks voor eigen gewin of verstoren van de functionaliteit van de website is <strong>niet toegestaan</strong>!</div>
<h2>Extra opgave</h2>
<p>Deze opgave leveren geen punten om, maar zijn wel leuk om te maken als je voor de rest alles al af hebt</p>
<ul>
<li><a href="/path">Insecure direct object references</a></li>
</ul>
{% endblock %}

@ -1,217 +0,0 @@
{% extends "base.html" %}
{% block content %}
<h1>Certificaten</h1>
<p>Deze week gaan we aan de slag met certificaten. De tool die we daarvoor gaan gebruiken is OpenSSL.
Dit is een veelgebruikt programma waar je vele cryptografische dingen mee kunt doen.</p>
<p>Op Linux en Mac OS X is deze tool al geïnstalleerd, Windows gebruikers moeten deze nog installeren. Als je <a href="http://google.nl/?q=openssl+windows+install" target="_blank">zoekt op het internet</a> vindt je verschillende mogelijkheden om dat te doen. Bijvoorbeeld de v.1.1.0f Light versie op <a href="http://slproweb.com/products/Win32OpenSSL.html" target="_blank">deze website</a>. Let op dat je dan op de Windows command line het hele pad moet gebruiken in plaats van alleen 'openssl'. Bijvoorbeeld: <span class="argument">C:\OpenSSL-Win32\bin\openssl.exe</span></p>
<p>Als je bij het gebruik van OpenSSL errors krijgt, probeer dan eerst je command prompt als Administrator te openen. En als dat ook niet werkt om het volgende commando uit te voeren:</p>
<code class="terminal">SET OPENSSL_CONF=[pad naar bestand]\openssl.cfg</code>
<hr>
<blockquote>Wie ben jij? En waarom zou ik jou vertrouwen dat je bent wie je zegt dat je bent?</blockquote>
<p>Dat zijn vragen die webbrowsers elke dag moeten beantwoorden. Een site kan wel vinden dat het www.rabobank.nl is, maar daarmee weet een browser nog niet zeker dat het ook daadwerkelijk de webserver van de Rabobank is. Misschien zit je eigenlijk te communiceren met een server ergens in Rusland van een persoon die maar al te graag je inlogcodes wil weten.</p>
<p>Om dit probleem op te lossen zijn er certificaten bedacht en vastgelegd in de <a href="http://en.wikipedia.org/wiki/X.509">X.509</a> standaard. Certificaten zijn kleine bestandjes waarin een identiteit staat beschreven. Dit is bijvoorbeeld een certificaat van Paul Wagener:</p>
<img src="/static/img/certificaat.png" class="center-block" style="border: 1px solid black">
<p>Nu wil jij natuurlijk meteen een eigen certificaat voor jezelf hebben, en dat kan! Met dit alles-in-1 commando maak je een certificaat dat helemaal van jou is:</p>
<code class="terminal">openssl req -x509 -nodes -newkey rsa:2048 -keyout sleutel.key -out certificaat.crt</code>
<p>Dit commando doet een paar dingen tegelijk waar we later op terugkomen. <b>Vul bij emailadres je Avans mailadres in</b>. Nadat je de gevraagde informatie hebt ingevuld staat er in het bestand certificaat.crt jouw certificaat. Met dit commando kan je je nieuwe certificaat bewonderen:</p>
<code class="terminal">openssl x509 -text -in certificaat.crt</code>
<div class="question">
<span class="question-string">Kopieer/plak de inhoud van certificaat.crt (inclusief begin en einde <code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_selfsigned_certificate.points max="10" %}
<textarea class="question-input" name="answer_openssl_selfsigned_certificate">{{ answers.answer_openssl_selfsigned_certificate.string }}</textarea>
</div>
<p>Een certificaat heeft ook altijd een <em>verstrekker</em> (issuer). Dit is de persoon of bedrijf die het certificaat heeft gemaakt en daarmee garant staat dat de identiteit die op het certificaat staat ook klopt. In jouw certificaat staat dat je over jezelf hebt gezegd dat je bent wie je zegt dat je bent. Niet echt betrouwbare informatie dus... Iedereen zou precies datzelfde certificaat kunnen maken.</p>
<p>Het wordt pas interessant en betrouwbaar als andere partijen het certificaat verstrekken en zo kunnen zeggen dat ze de gegevens van het certificaat gecontroleerd hebben.
Als jij die verstrekker vertrouwt dat hij zijn werk goed doet met de correctheid van certificaten controleren. Dan vertrouw je ook indirect de gegevens op het certificaat.
Zo hoef je maar een handjevol verstrekkers te vertrouwen om bijna alle websites op het internet te kunnen vertrouwen.</p>
<p>Elke besturingssysteem heeft een lijst van basis verstrekkers die ze impliciet vertrouwen, deze lijst kan je bekijken en veranderen door in je geavanceerde browserinstellingen op zoek te gaan naar een knop 'Beheer certificaten' (te vinden in het Advanced -> Certificates tabblad in Firefox).</p>
<p>
<div class="question">
<span class="question-string">Hoeveel basis verstrekkers vertrouwt jouw systeem? (je mag ook ongeveer een antwoord geven als het lastig tellen is)</span>
{% include "points.html" with points=answers.answer_openssl_number_of_issuers.points max="5" %}
<input class="question-input" name="answer_openssl_number_of_issuers" value="{{ answers.answer_openssl_number_of_issuers.string }}">
</div>
<div class="question">
<span class="question-string">Bekijk het certificaat van <a href="https://facebook.com/" target="_blank">Facebook</a>, welk bedrijf heeft dit certificaat verstrekt?</span>
{% include "points.html" with points=answers.answer_openssl_facebook_issuer.points max="5" %}
<input class="question-input" name="answer_openssl_facebook_issuer" value="{{ answers.answer_openssl_facebook_issuer.string }}">
</div>
<p class="hint">Hint: Het certificaat kan je in alle browsers bekijken door op het slot-ikoontje te klikken</p>
<h2>Mag ik uw handtekening?</h2>
<p>Zo'n certificaat wat je aan jezelf hebt verstrekt vertrouwd natuurlijk niemand. We moeten eerst iemand vinden die jouw certificaat wil ondertekenen.</p>
<p>Er is een speciaal bestandsformaat om aan een verstrekker te vragen of hij jouw certificaat wil ondertekenen: <b>.csr</b>. Dat staat voor Certificate Signing Request. Een soort van bedelbrief die je rond kan sturen met je certificaat waar nog een verstrekker bij moet.</p>
<p>Je kan onderstaand commando gebruiken om je eigen gemaakte certificaat als basis te gebruiken voor zo'n Certificate Signing Request:</p>
<code class="terminal">openssl x509 -x509toreq -in certificaat.crt -signkey sleutel.key -out certificaat_verzoek.csr</code>
<p>Zo'n verzoekje kan je vervolgens bij een certificaat autoriteit zoals Thawte of VeriSign inleveren. Voor een paar honderd euro zijn ze dan bereid om hun handtekening eronder te zetten.</p>
<p>Om deze les relatief goedkoop te houden heeft deze site ook een certificaat autoriteit waar je certificaten kan laten ondertekenen: <a href="/sign" target="signen">Certificaat Autoriteit</a>. Gebruik deze site om jouw certificaat te laten ondertekenen</p>
<div class="question">
<span class="question-string">Bekijk het certificaat wat je hebt teruggekregen. Welke persoon heeft dit certificaat aan jou verstrekt?</span>
{% include "points.html" with points=answers.answer_openssl_site_issuer.points max="5" %}
<input class="question-input" name="answer_openssl_site_issuer" value="{{ answers.answer_openssl_site_issuer.string }}">
</div>
<div class="question">
<span class="question-string">Plak jouw ondertekende certificaat in onderstaand tekstveld (inclusief begin en einde <code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_signed_cert.points max="10" %}
<textarea class="question-input" name="answer_openssl_signed_cert">{{ answers.answer_openssl_signed_cert.string }}</textarea>
</div>
<h2>Zelf verstrekken</h2>
<blockquote>Sometimes, the only one you can trust is yourself.</blockquote>
<p>Om zelf verstrekker te spelen heb je helemaal geen speciale certificaten nodig. Je kan namelijk gewoon je eigen certificaat en sleutel gebruiken die je aan het begin van de les hebt gemaakt. Vraag een medestudent om een Certificate Signing Request van zijn certificaat te geven en onderteken dat met je eigen certificaat. Zoek op internet het commando op waarmee je dat kan doen.</p>
<div class="question">
<span class="question-string">Plak de inhoud van het certificaat van een medestudent, waar je zelf verstrekker van bent. (inclusief begin en einde <code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_sign_other.points max="10" %}
<textarea class="question-input" name="answer_openssl_sign_other">{{ answers.answer_openssl_sign_other.string }}</textarea>
</div>
<p>Tip: zorg ervoor dat jouw certificaat standaard wordt geinstalleerd op alle besturingsystemen. Dan kan je goud geld verdienen met het ondertekenen van andere certificaten ;)</p>
<h2>Websites beveiligen</h2>
<p>Leuk die certificaten, maar laten we niet vergeten dat we er ook nog wat nuttigs mee kunnen doen. Namelijk onze internetverbindingen beveiligen. Om hiermee te oefenen moet je <a href="/static/vm.zip">deze virtual machine</a> downloaden. Het wachtwoord van deze VM is <b><i>sec2</i></b>. We hebben een aantal dingen gewijzigd hierin:</p>
<ul>
<li>Er is een default Apache installatie aanwezig.</li>
<li>www.security2.nl en sec1.aii.avans.nl wijzen naar de geïnstalleerde Apache op localhost.</li>
<li>We hebben <a href="/sign" target="signen">deze verstrekker</a> en het Let's Encrypt test certificaat als vertrouwd toegevoegd aan het systeem (dit kan je terugvinden als je in je browser gaat kijken naar alle certificaten die zijn geïnstalleerd)</li>
</ul>
<p>Controleer eerst of de site http://www.security2.nl in jouw VM te bereiken is, en via http<b>s</b>://www.security2.nl/ nog niet te bereiken is. Je gaat de site in de volgende opgaven beveiligen met SSL, om dat te doen moeten we eerst SSL aanzetten in Apache met de volgende commando's:</p>
<code class="terminal">sudo a2enmod ssl<br>
sudo a2ensite default-ssl<br>
sudo service apache2 reload</code>
<p class="hint">Hint: Commando's vul je in in het programma 'Terminal'</p>
<p>De site is nu ook via https:// bereikbaar, maar Apache heeft een ongeldig dummy certificaat gebruikt om de site te beveiligen. Om het werkend te krijgen moeten we eerst de volgende stappen uitvoeren:</p>
<ol>
<li>Maak een geheel nieuwe certificaat/sleutel combo aan met het commando bovenaan de pagina. Je mag alles invullen zoals je wil, behalve de Common Name / Server FQDN. Die moet <code>www.security2.nl</code> zijn.</li>
<li>Laat het certificaat <a href="/sign" target="signen">hier</a> weer ondertekenen</li>
<li>Kopieer het sleutel bestand en het ondertekende certificaat naar de VM</li>
<li>Voer het volgende commando uit: <code class="terminal">sudo gedit /etc/apache2/sites-available/default-ssl.conf</code> om de standaard SSL configuratie aan te passen.</li>
<li>Verander in dit bestand de <code>SSLCertificateFile</code> en <code>SSLCertificateKeyFile</code> zodat ze naar jouw certificaat en sleutel bestand wijzen</li>
<li>Maak je wijzigingen actief door de configuratie opnieuw in te laden: <code class="terminal">sudo service apache2 reload</code></li>
</ol>
<p>Als je alles goed hebt gedaan is de site nu met SSL beveiligd! Controleer of je de site in de VM nu kan bereiken via https://www.security2.nl/ (Alleen Chrome werkt, certificaat is niet aan Firefox toegevoegd). Als je een groen slotje krijgt mag je de volgende vraag beantwoorden:</p>
<div class="question">
<span class="question-string">Plak de inhoud van het .crt bestand dat je hebt gebruikt om de website te beveiligen met een groen slotje. (inclusief begin en einde <code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_ssl_cert.points max="10" %}
<textarea class="question-input" name="answer_openssl_ssl_cert">{{ answers.answer_openssl_ssl_cert.string }}</textarea>
</div>
<div class="question">
<span class="question-string">Maak een screenshot van het groene slotje en de details van het certificaat en upload die naar <a href="http://imgur.com" target="_blank">imgur</a>. Plak de URL naar die screenshot als antwoord.</span>
{% include "points.html" with points=answers.answer_openssl_screenshot.points max="10" %}
<input class="question-input" name="answer_openssl_screenshot" type="url" value="{{ answers.answer_openssl_screenshot.string }}">
</div>
<img src="/static/img/slotje_certificaat_vm.png" class="center-block screenshot" style="width: 60%" >
<h2>Let's Encrypt</h2>
<img src="/static/img/letsencrypt_logo.png" class="center-block">
<p><b><i>Let op, deze opdracht is dit jaar 0 punten waard omdat Avans een beveiliging heeft toegevoegd zodat het niet meer mogelijk is subdomeinen van avans.nl met Let's Encrypt te beveiligen.</i></b></p>
<p>Sinds 2015 is er <a href="https://letsencrypt.org/">een nieuwe speler</a> op de markt die gratis certificaten verstrekt, mits je kan bewijzen dat jouw website van jouw is natuurlijk. Dit gaat met behulp van de command-line <code>letsencrypt</code> tool die automatisch certificaten maakt en ondertekend voor jouw website. Deze tool hebben we al voor je geinstalleerd in de VM.</p>
<p>We gaan nu sec1.aii.avans.nl beveiligen, niet deze website die je nu aan het bekijken bent, maar weer de localhost die in de VM draait. Maar nu gaan we hem met behulp van Let's Encrypt beveiligen.</p>
<p><i>Tip:</i>Je mag voor deze opdracht ook een eigen domein dat je hebt beveiligen! Let even op dat de commando's dan niet overal exact hetzelfde zijn. Zeker als je geen Apache gebruikt.</p>
<p>Controleer eerst dat <b>https</b>://sec1.aii.avans.nl/ in de VM een fout geeft, dat komt omdat het certificaat van de vorige opdracht nog steeds van www.security2.nl is (als je de vorige opdracht goed hebt gedaan, anders krijg je misschien een andere fout). De browser ziet dat dat niet hetzelfde domein is en geeft terecht een error.</p>
<p>We gaan beginnen met het aanvragen van een certificaat. Dit doen we met het volgende commando:
<code class="terminal">sudo letsencrypt certonly --manual --staging</code>
<p>Even een korte uitleg van dit commando:</p>
<ul>
<li><b>sudo</b>: letsencrypt heeft root rechten nodig, we moeten letsencrypt dus altijd met root rechten uitvoeren</li>
<li><b>letsencrypt</b>: de naam van het scriptje zelf. Als je dit op je eigen server wil doen moet je deze eerst installeren (instructies vind je op de <a href="https://letsencrypt.org/getting-started/">Let's Encrypt website</a> zelf). Afhankelijk van hoe letsencrypt is geinstalleerd kan het commando ook <code>letsencrypt-auto</code>, <code>certbot</code> of <code>certbot-auto</code> zijn.</li>
<li><b>certonly</b>: Standaard wil Let's Encrypt volledig automatisch Apache voor je herconfigureren, maar dat gaat bij ons niet werken omdat de VM niet <i>echt</i> sec1.aii.avans.nl is. Met de certonly optie geven we aan dat we alleen geinteresseerd zijn in het maken van nieuwe certificaten.</li>
<li><b>--manual</b>: De Let's Encrypt servers geven niet zomaar certificaten weg, ze willen altijd zeker weten dat het domein waar je een certificaat van aanvraagt ook echt van jou is. Er zijn verschillende manieren om dat te doen, maar ze komen er allemaal op neer dat je een specifiek bestandje moet hosten op je website. Met de manual optie moeten we onze webserver zelf goed configureren dat het bestandje te bereiken is via het domein. De andere opties (<code>--webroot</code>, <code>--apache</code>) proberen het bestandje automatisch te plaatsen en de webserver te configureren. Dat gaat voor deze opdracht niet werken omdat de echte sec1.aii.avans.nl veilig ergens draait en van buiten niet te configureren is.</li>
<li><b>--staging</b>: Deze optie zorgt ervoor dat je een certificaat krijgt van de test server in plaats van de echte server. Deze hebben we nodig omdat de echte server een limiet heeft van 5 certificaataanvragen per week per domein. En dat is voor dit vak niet handig. Nadeel van de testserver is dat de certificaten een ongeldige fake verstrekker hebben (in de VM hebben we die fake verstrekker toegevoegd als vertrouwd, zodat je alsnog een groen slotje krijgt.)</li>
</ul>
<p>Als je dit commando voor de eerste keer uitvoert wordt er gevraagd naar je e-mailadres, daar kan je invullen wat je wil. Voor het domein gaan we sec1.aii.avans.nl invullen. Als je je eigen domein wil beveiligen vul je hier uiteraard je eigen domein in.</p>
<img src="/static/img/letsencrypt_domain.png" class="center-block screenshot" style="width: 80%" >
<p>Let's Encrypt vraagt daarna om een bestandje op de server te zetten in een hele specifieke map (.well-known/acme-challenge) op de echte sec1.aii.avans.nl server. Normaliter zou dit een probleem zijn, want dat kan alleen als je toegang hebt tot de server. Maar speciaal voor jullie is er <a href="/letsencrypt">een pagina</a> waar je de code kan kopieren en er voor zorgen dat het bestandje 10 minuten lang op onze server wordt gehost!</p>
<img src="/static/img/letsencrypt_challenge.png" class="center-block screenshot" style="width: 80%" >
<p>Nadat de challenge is geslaagd zal Let's Encrypt nog een melding geven over dat de self-verification failed (in de VM wijst sec1.aii.avans.nl immers naar de localhost, en niet naar het bestandje op de echte server). Maar dat kan je negeren, als het goed is gegaan staan de certificaten nu in de map <code>/etc/letsencrypt/live/sec1.aii.avans.nl</code>!.
<img src="/static/img/letsencrypt_congrats.png" class="center-block screenshot" style="width: 80%" >
<p>Met dit commando kan je je nieuwe certificaat bekijken:</p>
<code class="terminal">sudo gedit /etc/letsencrypt/live/sec1.aii.avans.nl/fullchain.pem</code>
<div class="question">
<span class="question-string">Plak de inhoud van het <code>fullchain.pem</code> certificaat voor sec1.aii.avans.nl. (inclusief alle begin en einde <code>-----BEGIN CERTIFICATE-----</code>)</span>
{% include "points.html" with points=answers.answer_openssl_letsencrypt_fullchain.points max="0" %}
<textarea class="question-input" name="answer_openssl_letsencrypt_fullchain">{{ answers.answer_openssl_letsencrypt_fullchain.string }}</textarea>
</div>
<p>Stel het default-ssl.conf configuratie bestand van Apache nu zo in dat het de certificaten van Let's Encrypt gebruikt:</p>
<img src="/static/img/letsencrypt_conf.png" class="center-block screenshot" >
<p>Sla het bestand op, reload Apache en als het goed is heb je nu een beveiligde https://sec1.aii.avans.nl/, helemaal gratis en voor niets!</p>
<img src="/static/img/letsencrypt_chrome.png" class="center-block screenshot" style="width: 90%" >
<p>Het zal je misschien opvallen dat de verstrekker Fake is, dat komt omdat we de <code>--staging</code> optie hebben gebruikt. In de VM is deze toegevoegd als iets dat we kunnen vertrouwen (en dus een groen slotje oplevert), maar in de echte wereld is dat niet zo. Zorg er dus bij je eigen website zo dat je niet de --staging optie gebruikt als je voor de echie certificaten aan het maken bent</p>
<div class="question">
<span class="question-string">Maak een screenshot van het groene slotje en de details van het certificaat (zoals hierboven, maar natuurlijk niet letterlijk dat plaatje, dat hebben we door) en upload die naar <a href="http://imgur.com" target="_blank">imgur</a>. Plak de URL naar die screenshot als antwoord.</span>
{% include "points.html" with points=answers.answer_openssl_letsencrypt_screenshot.points max="0" %}
<input class="question-input" name="answer_openssl_letsencrypt_screenshot" type="url" value="{{ answers.answer_openssl_letsencrypt_screenshot.string }}">
</div>
{% endblock %}

@ -1,149 +1,232 @@
{% extends "base.html" %}
{% block content %}
<h1>Encryptie &amp; Signen</h1>
<p>Deze week gaan we nog een laagje dieper en kijken naar (a)symmetrische encryptie, sleutels, signen en PGP.</p>
<h2>Symmetrische encryptie</h2>
<p>Dat encryptie betekent dat je bestandjes of tekst versleuteld wist je waarschijnlijk al, maar wist je ook dat er twee soorten encryptie zijn? Symmetrische en assymetrische encryptie zijn verschillende technieken die je beide in tandem kan gebruiken om je bestanden, berichten en verbindingen te beveiligen.</p>
<p>Stel, Alice wil een geheim bericht versturen naar Bob. Alice kan het bericht geheim maken door het door een encryptiealgoritme te halen. Dit neemt het bericht van Alice en een geheime sleutel als input. De sleutel is in dit geval een random string die alleen Alice weet. Het algoritme encrypt het bericht naar een gecodeerde versie. Zonder de sleutel te hebben is het onmogelijk om terug te rekenen wat het originele bericht was. Alice stuurt met een gerust hart dit gecodeerde bericht via internet delen, zonder bang te zijn dat iemand het kan lezen.</p>
<img src="static/img/sym_encryptie.png">
<p>Alice wil het bericht aan Bob sturen, om ervoor te zorgen dat Bob het bericht kan ontcijferen heeft Alice hem de geheime sleutel van tevoren gegeven. Bob kan het gecodeerde bericht samen met <b>dezelfde</b> geheime sleutel die Alice heeft gebruikt door het bijbehorende decryptie algoritme halen om de originele data weer terug te krijgen.</p>
<p>Bob kan op dezelfde manier ook berichten naar Alice sturen die Alice weer kan ontcijferen. Zolang de sleutel geheim blijft kunnen Alice en Bob veilig met elkaar communiceren.</p>
<img src="static/img/sym_decryptie.png">
<p>We kunnen met OpenSSL (zie vorige week als je dat nog niet hebt geinstalleerd) ook encrypten en decrypten met verschillende soorten encryptie algoritmes. Met onderstaande commando kunnen we bijvoorbeeld een bestand ontsleutelen.</p>
<code class="terminal">openssl enc -aes-256-cbc -base64 -d -in geheim.aes256 -out nietmeergeheim.txt</code>
<p>Een hele mond vol, laten we eens kijken wat alle argumenten betekenen:</p>
<ul>
<li><span class="argument">openssl</span> Het programma zelf</li>
<li><span class="argument">enc</span> Een command van OpenSSL waarmee we aangeven dat we data willen versleutelen of ontsleutelen</li>
<li><span class="argument">-aes-256-cbc</span> Het encryptie algoritme wat we gebruiken.
<ul>
<li><b>aes</b> staat voor <a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard" target="_blank">Advanced Encryption Standard</a>, een veel gebruikt algoritme.</li>
<li><b>256</b> is het aantal bits van de sleutel. OpenSSL vult je wachtwoord aan tot deze hoeveelheid bits.</li>
<li><b>cbc</b> staat voor <a href="https://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29." target="_blank">Cipher-block chaining</a>. Een techniek om het lastiger te maken informatie af te leiden uit de versleutelde data.</li>
</ul>
</li>
<li><span class="argument">-base64</span> lees en schrijf de versleutelde data als <a href="http://en.wikipedia.org/wiki/Base64" target="_blank">base64</a>. Dit maakt bestandjes groter, maar de data ook makkelijker te knippen/plakken in mailtjes of invoervelden op websites.</li>
<li><span class="argument">-d</span> decryptie modus. Met dit argument geef je aan dat de invoer de versleutelde data is en de uitvoer de oorspronkelijke data moet zijn.
Als je deze optie niet mee geeft zit je in encryptie modus, de invoer is dan de oorspronkelijke data en de uitvoer wordt dan de versleutelde data</li>
<li><span class="argument">-in geheim.txt</span> het invoerbestand</li>
<li><span class="argument">-out decrypted.txt</span> het uitvoerbestand</li>
</ul>
<img src="/static/img/encryptie.jpg" class="center-block" style="margin-top: 1em; margin-bottom: 1em">
<p>Een systeembeheerder heeft een geheim staan in dit <a href="/static/geheim.aes256" target="_blank">bestandje</a> wat hij met aes-256-cbc heeft versleuteld. Helaas voor hem heeft hij een niet zo hele sterke sleutel gekozen: <code>Ab12345</code>. Gebruik OpenSSL om dit bestandje te ontsleutelen.</p>
<div class="question">
<span class="question-string">Wat is de geheime code die in dit versleutelde bestandje staat?</span>
{% include "points.html" with points=answers.answer_encryption_decrypt.points max="10" %}
<input class="question-input" name="answer_encryption_decrypt" value="{{ answers.answer_encryption_decrypt.string }}"></input>
</div>
<p class="hint">Hint: Als je een bad decrypt error krijgt heb je waarschijnlijk een OpenSSL versie die lager is dan 1.1.0. In dat geval moet je de optie `-md sha256` toevoegen.</code></p>
<div class="question">
<span class="question-string">Versleutel de tekst "<em>Avans Hogeschool</em>" met het aes-256-cbc algoritme in base64 mode. Plak de versleutelde tekst in het tekstveld, gebruik <code>Ab12345</code> als wachtwoord.</span>
{% include "points.html" with points=answers.answer_encryption_encrypt.points max="10" %}
<textarea class="question-input" name="answer_encryption_encrypt">{{ answers.answer_encryption_encrypt.string }}</textarea>
</div>
<p class="hint">Hint: Je kan dit commando gebruiken: <code class="terminal">openssl enc -aes-256-cbc -base64 -in avans.txt -out avansgeheim.aes256.txt</code></p>
<h2>Asymmetrische encryptie</h2>
<p>Bij symmetrische encryptie gebruiken Alice en Bob allebei dezelfde sleutel om het bestand te versleutelen en te ontsleutelen. Maar hun communicatie is alleen veilig als ze de sleutel in het geheim afspreken en zolang ze de sleutel geheim houden. Dit probleem is opgelost bij asymmetrische encryptie algoritmes, waarbij je twee sleutels gebruikt. Eén publieke en één privé sleutel.</p>
<p>Bij een asymmetrisch encryptiealgoritme kan je niet zelf een random sleutel kiezen, deze moet je genereren met een speciaal key-generation algoritme. Deze geeft random twee sleutels terug die een opmerkelijke relatie met elkaar hebben. Om ze uit elkaar te halen noemen we ze hier de groene en de rode sleutel, maar het maakt in de praktijk niet uit welke sleutel welke is.</p>
<img src="static/img/sleutels_genereren.png">
<p>Om een bestandje te versleutelen nemen we bijvoorbeeld de groene sleutel en gebruiken we die om het bestandje te versleutelen. Maar we kunnen het bestand nu niet meer ontsleutelen met de groene sleutel. <b>Met alleen de bijbehorende rode sleutel kan je nu het bestand ontsleutelen</b>. Andersom werkt ook, bestanden die je met de rode sleutel versleuteld, zijn enkel en alleen met de groene sleutel te ontsleutelen.</p>
<img src="static/img/asym_encryptie.png">
<p>Dit lijkt allemaal wat omslachtig en onhandig, en asymmetrische encryptie is ook nog eens honderden keren langzamer dan symmetrische encryptie. Waarom zouden we dit gebruiken?</p>
<p>Asymmetrische encryptie vormt de basis van het public-private key systeem. Nadat we een sleutel-paartje hebben gegenereerd geven we één sleutel weg aan alles en iedereen, dat is de publieke sleutel die iedereen kan gebruiken. De andere bijbehorende sleutel bewaren we op de geheimste plek die je maar kan bedenken en geef je onder geen enkele omstandigheid aan iemand anders.</p>
<img src="static/img/publicprivatekey.png">
<p>Als Alice nu een geheim bericht aan Bob wil versturen kan ze dit versleutelen door gebruik te maken van Bob's publieke sleutel. Het versleutelde bericht is enkel en alleen te ontsleutelen met Bob's bijbehorende private sleutel. Alice weet dus zeker dat alleen Bob het kan lezen.</p>
<img src="static/img/asym_alicebob.png">
<p>Als Alice het bericht met haar private key zou versleutelen ontstaat er een andere interessante eigenschap: Iedereen kan het bericht ontsleutelen, dat is te doen met de bijbehorende publieke sleutel. Maar je weet dan wel zeker dat het bericht van Alice afkomstig is, want alleen zij heeft de private sleutel waarmee het bericht in de eerste plaats versleuteld is.
<div class="question">
<span class="question-string">Hoe kan Alice één bericht naar Bob versturen zodat de volgende dingen tegelijkertijd gelden:
<ol>
<li>Alleen Bob kan het bericht lezen</li>
<li>Bob weet zeker dat het bericht van Alice is</li>
</ol>
Leg uit in welke volgorde Alice en Bob encrypten, decrypten en versturen en met welke sleutels. Je mag er van uit gaan dat ze elkaars publieke sleutel weten en dat Bob niet de enige is met Alice's publieke sleutel.
</span>
{% include "points.html" with points=answers.answer_encryption_securesend.points max="10" %}
<textarea class="question-input" name="answer_encryption_securesend">{{ answers.answer_encryption_securesend.string }}</textarea>
</div>
<p class="hint"><strong>Hint:</strong> het is natuurlijk mogelijk om een versleuteld bericht nog een keer te versleutelen.</p>
<img src="static/img/whatsapp.png" class="screenshot center-block" style="width: 70%">
<p>WhatsApp beweert dat alle berichten end-to-end versleuteld verstuurd worden. Daarmee zou niemand de berichten kunnen lezen die via hun servers verstuurd worden, zelfs zij zelf niet. Alleen de afzender en de ontvanger kunnen de berichten lezen.</p>
<p>Om dat te controleren kan je bij de contactinformatie van elke chat klikken op 'Encryptie', je krijgt dan een QR code en een lijst van cijfers. Als de cijfers allemaal hetzelfde zijn zou je zeker moeten weten dat berichtjes alleen door jou en de andere persoon gelezen kunnen worden.</p>
<img src="static/img/whatsapp_qr.png" class="screenshot center-block" style="width: 50%">
<div class="question">
<span class="question-string">Zoek op internet welke informatie er in de QR code staat. Hoe kan WhatsApp met die informatie garanderen dat alleen jullie twee de chat kan lezen?</span>
{% include "points.html" with points=answers.answer_encryption_whatsapp.points max="10" %}
<textarea class="question-input" name="answer_encryption_whatsapp">{{ answers.answer_encryption_whatsapp.string }}</textarea>
</div>
<h2>GPG</h2>
<p>Genoeg theorie, we gaan aan de slag met concrete encryptiealgoritmes. En wel met de <a href="http://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP" target="_blank">OpenPGP</a> (Pretty Good Privacy) standaard. Een veel gebruikt open source programma die deze standaard implementeert is <a href="http://en.wikipedia.org/wiki/GNU_Privacy_Guard" target="_blank">GPG</a> (GNU Privacy Guard). Met dit programma kunnen we sleutelparen maken, bestanden encrypten/decrypten en versleutelde berichten versturen.</p>
<p>Om het makkelijker te maken om publieke sleutels uit te wisselen kan GPG gebruik maken van een <b>keyserver</b>. Dit is een speciale server die een lijst van publieke sleutels bijhoud. Voor onderstaande opdrachten hebben we onze eigen keyserver ingericht op sec1.aii.avans.nl. <b>Deze werkt niet als je de opdrachten thuis maakt</b>. De Avans firewall blokkeert poort 11371 waarop deze server werkt. Als je thuis de opdrachten wilt maken kan je het beste <a href="https://vmview-1.aii.avans.nl/" target="_blank">inloggen</a> op een PANO-box VM. Daar werkt het wel.</p>
<p>GPG kan je <a href="http://www.gpg4win.org/" target="_blank">hier</a> voor Windows downloaden, na het installeren kan je in je CMD alle commando's typen. Als je Linux of Mac OS X gebruikt hoef je niks te doen, GPG is standaard geïnstalleerd.</p>
<img src="static/img/gpg.png">
<code class="terminal">gpg --help</code>
<p>Met bovenstaande commando zie je alle dingen die je met GPG kan doen. We gaan niet meer alle commando's voorkauwen, je bent inmiddels handig genoeg om die zelf te bedenken. Een paar handige opties om te onthouden:</p>
<ul>
<li><b>--gen-key</b> Maak een nieuw publiek/private sleutelpaar.</li>
<li><b>--list-keys</b> Bekijk alle sleutels die je lokaal hebt.</li>
<li><b>--sign</b> Gebruik je eigen private sleutel gebruiken om een bestand te encrypten.</li>
<li><b>--decrypt</b> Gebruik iemand anders publieke sleutel om een bestand te decrypten.</li>
<li><b>--encrypt</b> Gebruik iemand anders publieke sleutel om een bestand te encrypten.</li>
<li><b>--recv-keys --keyserver sec1.aii.avans.nl <i>sleutel-ID</i></b> Haal een publieke sleutel op van de onze keyserver</li>
<li><b>--send-keys --keyserver sec1.aii.avans.nl <i>sleutel-ID</i></b> Verstuur een publieke sleutel naar onze keyserver</li>
<li><b>--sign-key</b> Signeer een publieke sleutel met jouw eigen private sleutel</li>
<li><b>-a</b> Output in ASCII base64 formaat</li>
<p>
<p>Haal van de keyserver onze publieke sleutel op met sleutel-ID <b>B69F77232CE5546445137725D555F2F5FA9E1C5A</b> (GPG noemt dit ook wel de user-ID). We hebben met onze private sleutel een tekst versleuteld in <a href="static/secret.txt.asc" target="_blank">dit bestand</a>. Gebruik de publieke sleutel om dit bestand te ontsleutelen.</p>
{% extends "base.html" %} {% block content %}
<h1>Encryptie &amp; Signen</h1>
<p>Deze week gaan we nog een laagje dieper en kijken naar (a)symmetrische encryptie, sleutels, signen en PGP.</p>
<h2>Symmetrische encryptie</h2>
<p>Dat encryptie betekent dat je bestandjes of tekst versleuteld wist je waarschijnlijk al, maar wist je ook dat er twee soorten
encryptie zijn? Symmetrische en assymetrische encryptie zijn verschillende technieken die je beide in tandem kan gebruiken
om je bestanden, berichten en verbindingen te beveiligen.</p>
<p>Stel, Alice wil een geheim bericht versturen naar Bob. Alice kan het bericht geheim maken door het door een encryptiealgoritme
te halen. Dit neemt het bericht van Alice en een geheime sleutel als input. De sleutel is in dit geval een random string
die alleen Alice weet. Het algoritme encrypt het bericht naar een gecodeerde versie. Zonder de sleutel te hebben is het
onmogelijk om terug te rekenen wat het originele bericht was. Alice stuurt met een gerust hart dit gecodeerde bericht via
internet delen, zonder bang te zijn dat iemand het kan lezen.</p>
<img src="static/img/sym_encryptie.png">
<p>Alice wil het bericht aan Bob sturen, om ervoor te zorgen dat Bob het bericht kan ontcijferen heeft Alice hem de geheime
sleutel van tevoren gegeven. Bob kan het gecodeerde bericht samen met
<b>dezelfde</b> geheime sleutel die Alice heeft gebruikt door het bijbehorende decryptie algoritme halen om de originele data
weer terug te krijgen.</p>
<p>Bob kan op dezelfde manier ook berichten naar Alice sturen die Alice weer kan ontcijferen. Zolang de sleutel geheim blijft
kunnen Alice en Bob veilig met elkaar communiceren.</p>
<img src="static/img/sym_decryptie.png">
<p>We kunnen met OpenSSL (zie vorige week als je dat nog niet hebt geinstalleerd) ook encrypten en decrypten met verschillende
soorten encryptie algoritmes. Met onderstaande commando kunnen we bijvoorbeeld een bestand ontsleutelen.</p>
<code class="terminal">openssl enc -aes-256-cbc -base64 -d -in geheim.aes256 -out nietmeergeheim.txt</code>
<p>Een hele mond vol, laten we eens kijken wat alle argumenten betekenen:</p>
<ul>
<li>
<span class="argument">openssl</span> Het programma zelf</li>
<li>
<span class="argument">enc</span> Een command van OpenSSL waarmee we aangeven dat we data willen versleutelen of ontsleutelen</li>
<li>
<span class="argument">-aes-256-cbc</span> Het encryptie algoritme wat we gebruiken.
<ul>
<li>
<b>aes</b> staat voor
<a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard" target="_blank">Advanced Encryption Standard</a>, een veel gebruikt algoritme.</li>
<li>
<b>256</b> is het aantal bits van de sleutel. OpenSSL vult je wachtwoord aan tot deze hoeveelheid bits.</li>
<li>
<b>cbc</b> staat voor
<a href="https://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29." target="_blank">Cipher-block chaining</a>. Een techniek om het lastiger te maken informatie af te leiden uit de versleutelde data.</li>
</ul>
</li>
<li>
<span class="argument">-base64</span> lees en schrijf de versleutelde data als
<a href="http://en.wikipedia.org/wiki/Base64" target="_blank">base64</a>. Dit maakt bestandjes groter, maar de data ook makkelijker te knippen/plakken in mailtjes of invoervelden
op websites.</li>
<li>
<span class="argument">-d</span> decryptie modus. Met dit argument geef je aan dat de invoer de versleutelde data is en de uitvoer de oorspronkelijke
data moet zijn. Als je deze optie niet mee geeft zit je in encryptie modus, de invoer is dan de oorspronkelijke data
en de uitvoer wordt dan de versleutelde data</li>
<li>
<span class="argument">-in geheim.txt</span> het invoerbestand</li>
<li>
<span class="argument">-out decrypted.txt</span> het uitvoerbestand</li>
</ul>
<img src="/static/img/encryptie.jpg" class="center-block" style="margin-top: 1em; margin-bottom: 1em">
<p>Een systeembeheerder heeft een geheim staan in dit
<a href="/static/geheim.aes256" target="_blank">bestandje</a> wat hij met aes-256-cbc heeft versleuteld. Helaas voor hem heeft hij een niet zo hele sterke sleutel gekozen:
<code>Ab12345</code>. Gebruik OpenSSL om dit bestandje te ontsleutelen.</p>
<div class="question">
<span class="question-string">Wat is de geheime code die in dit versleutelde bestandje staat?</span>
{% include "points.html" with points=answers.answer_encryption_decrypt.points max="10" %}
<input class="question-input" name="answer_encryption_decrypt" value="{{ answers.answer_encryption_decrypt.string }}"></input>
</div>
<p class="hint">Hint: Als je een bad decrypt error krijgt heb je waarschijnlijk een OpenSSL versie die lager is dan 1.1.0. In dat geval moet
je de optie `-md sha256` toevoegen.</code>
</p>
<div class="question">
<span class="question-string">Versleutel de tekst "
<em>Security Workshop</em>" met het aes-256-cbc algoritme in base64 mode. Plak de versleutelde tekst in het tekstveld, gebruik
<code>Ab12345</code> als wachtwoord.</span>
{% include "points.html" with points=answers.answer_encryption_encrypt.points max="10" %}
<textarea class="question-input" name="answer_encryption_encrypt">{{ answers.answer_encryption_encrypt.string }}</textarea>
</div>
<p class="hint">Hint: Je kan dit commando gebruiken:
<code class="terminal">openssl enc -aes-256-cbc -base64 -in plain.txt -out geheim.aes256.txt</code>
</p>
<h2>Asymmetrische encryptie</h2>
<p>Bij symmetrische encryptie gebruiken Alice en Bob allebei dezelfde sleutel om het bestand te versleutelen en te ontsleutelen.
Maar hun communicatie is alleen veilig als ze de sleutel in het geheim afspreken en zolang ze de sleutel geheim houden.
Dit probleem is opgelost bij asymmetrische encryptie algoritmes, waarbij je twee sleutels gebruikt. Eén publieke en één
privé sleutel.</p>
<p>Bij een asymmetrisch encryptiealgoritme kan je niet zelf een random sleutel kiezen, deze moet je genereren met een speciaal
key-generation algoritme. Deze geeft random twee sleutels terug die een opmerkelijke relatie met elkaar hebben. Om ze uit
elkaar te halen noemen we ze hier de groene en de rode sleutel, maar het maakt in de praktijk niet uit welke sleutel welke
is.
</p>
<img src="static/img/sleutels_genereren.png">
<p>Om een bestandje te versleutelen nemen we bijvoorbeeld de groene sleutel en gebruiken we die om het bestandje te versleutelen.
Maar we kunnen het bestand nu niet meer ontsleutelen met de groene sleutel.
<b>Met alleen de bijbehorende rode sleutel kan je nu het bestand ontsleutelen</b>. Andersom werkt ook, bestanden die je met
de rode sleutel versleuteld, zijn enkel en alleen met de groene sleutel te ontsleutelen.</p>
<img src="static/img/asym_encryptie.png">
<p>Dit lijkt allemaal wat omslachtig en onhandig, en asymmetrische encryptie is ook nog eens honderden keren langzamer dan symmetrische
encryptie. Waarom zouden we dit gebruiken?</p>
<p>Asymmetrische encryptie vormt de basis van het public-private key systeem. Nadat we een sleutel-paartje hebben gegenereerd
geven we één sleutel weg aan alles en iedereen, dat is de publieke sleutel die iedereen kan gebruiken. De andere bijbehorende
sleutel bewaren we op de geheimste plek die je maar kan bedenken en geef je onder geen enkele omstandigheid aan iemand
anders.
</p>
<img src="static/img/publicprivatekey.png">
<p>Als Alice nu een geheim bericht aan Bob wil versturen kan ze dit versleutelen door gebruik te maken van Bob's publieke sleutel.
Het versleutelde bericht is enkel en alleen te ontsleutelen met Bob's bijbehorende private sleutel. Alice weet dus zeker
dat alleen Bob het kan lezen.</p>
<img src="static/img/asym_alicebob.png">
<p>Als Alice het bericht met haar private key zou versleutelen ontstaat er een andere interessante eigenschap: Iedereen kan
het bericht ontsleutelen, dat is te doen met de bijbehorende publieke sleutel. Maar je weet dan wel zeker dat het bericht
van Alice afkomstig is, want alleen zij heeft de private sleutel waarmee het bericht in de eerste plaats versleuteld is.
<div class="question">
<span class="question-string">Hoe kan Alice één bericht naar Bob versturen zodat de volgende dingen tegelijkertijd gelden:
<ol>
<li>Alleen Bob kan het bericht lezen</li>
<li>Bob weet zeker dat het bericht van Alice is</li>
</ol>
Leg uit in welke volgorde Alice en Bob encrypten, decrypten en versturen en met welke sleutels. Je mag er van uit gaan dat
ze elkaars publieke sleutel weten en dat Bob niet de enige is met Alice's publieke sleutel.
</span>
{% include "points.html" with points=answers.answer_encryption_securesend.points max="10" %}
<textarea class="question-input" name="answer_encryption_securesend">{{ answers.answer_encryption_securesend.string }}</textarea>
</div>
<p class="hint">
<strong>Hint:</strong> het is natuurlijk mogelijk om een versleuteld bericht nog een keer te versleutelen.</p>
<img src="static/img/whatsapp.png" class="screenshot center-block" style="width: 70%">
<p>WhatsApp beweert dat alle berichten end-to-end versleuteld verstuurd worden. Daarmee zou niemand de berichten kunnen lezen
die via hun servers verstuurd worden, zelfs zij zelf niet. Alleen de afzender en de ontvanger kunnen de berichten lezen.</p>
<p>Om dat te controleren kan je bij de contactinformatie van elke chat klikken op 'Encryptie', je krijgt dan een QR code en
een lijst van cijfers. Als de cijfers allemaal hetzelfde zijn zou je zeker moeten weten dat berichtjes alleen door jou
en de andere persoon gelezen kunnen worden.</p>
<img src="static/img/whatsapp_qr.png" class="screenshot center-block" style="width: 50%">
<div class="question">
<span class="question-string">Zoek op internet welke informatie er in de QR code staat. Hoe kan WhatsApp met die informatie garanderen dat alleen jullie
twee de chat kan lezen?</span>
{% include "points.html" with points=answers.answer_encryption_whatsapp.points max="10" %}
<textarea class="question-input" name="answer_encryption_whatsapp">{{ answers.answer_encryption_whatsapp.string }}</textarea>
</div>
<h2>GPG</h2>
<p>Genoeg theorie, we gaan aan de slag met concrete encryptiealgoritmes. En wel met de
<a href="http://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP" target="_blank">OpenPGP</a> (Pretty Good Privacy) standaard. Een veel gebruikt open source programma die deze standaard implementeert
is
<a href="http://en.wikipedia.org/wiki/GNU_Privacy_Guard" target="_blank">GPG</a> (GNU Privacy Guard). Met dit programma kunnen we sleutelparen maken, bestanden encrypten/decrypten en versleutelde
berichten versturen.</p>
<p>Om het makkelijker te maken om publieke sleutels uit te wisselen kan GPG gebruik maken van een
<b>keyserver</b>. Dit is een speciale server die een lijst van publieke sleutels bijhoud. Voor onderstaande opdrachten hebben
we onze eigen keyserver ingericht op websec.paulwagener.nl.
<b>Deze werkt niet als je de opdrachten thuis maakt</b>. De Avans firewall blokkeert poort 11371 waarop deze server werkt.</p>
<p>GPG kan je
<a href="http://www.gpg4win.org/" target="_blank">hier</a> voor Windows downloaden, na het installeren kan je in je CMD alle commando's typen. Als je Linux of Mac OS X
gebruikt hoef je niks te doen, GPG is standaard geïnstalleerd.</p>
<img src="static/img/gpg.png">
<code class="terminal">gpg --help</code>
<p>Met bovenstaande commando zie je alle dingen die je met GPG kan doen. We gaan niet meer alle commando's voorkauwen, je
bent inmiddels handig genoeg om die zelf te bedenken. Een paar handige opties om te onthouden:</p>
<ul>
<li>
<b>--gen-key</b> Maak een nieuw publiek/private sleutelpaar.</li>
<li>
<b>--list-keys</b> Bekijk alle sleutels die je lokaal hebt.</li>
<li>
<b>--sign</b> Gebruik je eigen private sleutel gebruiken om een bestand te encrypten.</li>
<li>
<b>--decrypt</b> Gebruik iemand anders publieke sleutel om een bestand te decrypten.</li>
<li>
<b>--encrypt</b> Gebruik iemand anders publieke sleutel om een bestand te encrypten.</li>
<li>
<b>--recv-keys --keyserver websec.paulwagener.nl
<i>sleutel-ID</i>
</b> Haal een publieke sleutel op van de onze keyserver</li>
<li>
<b>--send-keys --keyserver websec.paulwagener.nl
<i>sleutel-ID</i>
</b> Verstuur een publieke sleutel naar onze keyserver</li>
<li>
<b>--sign-key</b> Signeer een publieke sleutel met jouw eigen private sleutel</li>
<li>
<b>-a</b> Output in ASCII base64 formaat</li>
<p>
<p>Haal van de keyserver onze publieke sleutel op met sleutel-ID
<b>B69F77232CE5546445137725D555F2F5FA9E1C5A</b> (GPG noemt dit ook wel de user-ID). We hebben met onze private sleutel
een tekst versleuteld in
<a href="static/secret.txt.asc" target="_blank">dit bestand</a>. Gebruik de publieke sleutel om dit bestand te ontsleutelen.</p>
<div class="question">
<span class="question-string">Welke zin hebben we versleuteld?</span>
@ -151,72 +234,79 @@
<input class="question-input" name="answer_encryption_decrypt_public_key" value="{{ answers.answer_encryption_decrypt_public_key.string }}">
</div>
<p>Gebruik onze publieke sleutel om zelf een tekstbestandje te versleutelen. Zorg ervoor dat ergens in de tekst van dit bestandje de geheime code "555-0690" en je Avans e-mailadres staat.</p>
<p>Gebruik onze publieke sleutel om zelf een tekstbestandje te versleutelen. Zorg ervoor dat ergens in de tekst van dit
bestandje de geheime code "555-0690" en je e-mailadres staat.</p>
<div class="question">
<span class="question-string">Plak de inhoud van het versleutelde bestand (inclusief begin en einde <code>-----BEGIN PGP MESSAGE-----</code>)</span>
<span class="question-string">Plak de inhoud van het versleutelde bestand (inclusief begin en einde
<code>-----BEGIN PGP MESSAGE-----</code>)</span>
{% include "points.html" with points=answers.answer_encryption_encrypt_public_key.points max="5" %}
<textarea class="question-input" name="answer_encryption_encrypt_public_key">{{ answers.answer_encryption_encrypt_public_key.string }}</textarea>
</div>
<p class="hint"><strong>Hint:</strong> Het is met GPG mogelijk om meerdere ontvangers op te geven. Dat hoeft voor deze opdracht niet. Als je alle (1 dus) ontvangers hebt opgegeven moet je een lege regel opgeven om aan te geven dat je verder wil gaan.</p>
<p class="hint">
<strong>Hint:</strong> Het is met GPG mogelijk om meerdere ontvangers op te geven. Dat hoeft voor deze opdracht niet. Als
je alle (1 dus) ontvangers hebt opgegeven moet je een lege regel opgeven om aan te geven dat je verder wil gaan.</p>
<p class="hint"><strong>Hint:</strong> Gebruik onze sleutel-ID (ook wel user-id) die we eerder al hebben genoemd.</p>
<p class="hint">
<strong>Hint:</strong> Gebruik onze sleutel-ID (ook wel user-id) die we eerder al hebben genoemd.</p>
<p class="hint"><strong>Hint:</strong> Krijg je een binair bestand? Dan ben je waarschijnlijk vergeten om de ASCII base64 optie aan te zetten (zie lijst van opties hierboven)</p>
<p class="hint">
<strong>Hint:</strong> Krijg je een binair bestand? Dan ben je waarschijnlijk vergeten om de ASCII base64 optie aan te zetten
(zie lijst van opties hierboven)</p>
<p>Tijd om je eigen sleutels te gebruiken! Maak je eigen publieke/private sleutelpaar en verstuur de publieke sleutel naar de sec1.aii.avans.nl keyserver. <b>Gebruik je Avans e-mailadres voor het e-mailveld</b>.</p>
<p>Tijd om je eigen sleutels te gebruiken! Maak je eigen publieke/private sleutelpaar en verstuur de publieke sleutel
naar de websec.paulwagener.nl keyserver.
<b>Gebruik je e-mailadres voor het e-mailveld</b>.</p>
<p>Vergeet niet om je publieke sleutel naar de sec1.aii.avans.nl keyserver te sturen zodat anderen die kunnen opzoeken en geheime berichten naar je kunnen sturen (en zodat wij de opdrachten kunnen nakijken, anders krijg je de punten voor onderstaande opdracht niet!)</p>
<p>Vergeet niet om je publieke sleutel naar de websec.paulwagener.nl keyserver te sturen zodat anderen die kunnen opzoeken
en geheime berichten naar je kunnen sturen (en zodat wij de opdrachten kunnen nakijken, anders krijg je de punten
voor onderstaande opdracht niet!)</p>
<div class="question">
<span class="question-string">Versleutel een bestandje met de tekst "Security 2" met je eigen private sleutel. Plak de versleutelde tekst in het tekstveld (inclusief begin en einde <code>-----BEGIN PGP MESSAGE-----</code>)</span>
<span class="question-string">Versleutel een bestandje met de tekst "Security 2" met je eigen private sleutel. Plak de versleutelde tekst in het
tekstveld (inclusief begin en einde
<code>-----BEGIN PGP MESSAGE-----</code>)</span>
{% include "points.html" with points=answers.answer_encryption_encrypt_with_own_private.points max="5" %}
<textarea class="question-input" name="answer_encryption_encrypt_with_own_private">{{ answers.answer_encryption_encrypt_with_own_private.string }}</textarea>
</div>
<h3>Web of Trust</h3>
<p>Probleempje: elke mafketel kan sleutels aanmaken en daar elke naam bij zetten die hij maar wil. Hoe zorgen we ervoor dat de naam en e-mailadres die bij een sleutel staan ook echt klopt? Dit probleem heeft GPG opgelost door het mogelijk te maken om met jouw private sleutel een <b>handtekening</b> (signature) te maken voor een publieke sleutel van iemand anders. Je geeft daarmee aan dat je gecontroleerd hebt dat de naam die bij een sleutel staat klopt en dat je die persoon vertrouwd.</p>
<p>Probleempje: elke mafketel kan sleutels aanmaken en daar elke naam bij zetten die hij maar wil. Hoe zorgen we ervoor
dat de naam en e-mailadres die bij een sleutel staan ook echt klopt? Dit probleem heeft GPG opgelost door het mogelijk
te maken om met jouw private sleutel een
<b>handtekening</b> (signature) te maken voor een publieke sleutel van iemand anders. Je geeft daarmee aan dat je gecontroleerd
hebt dat de naam die bij een sleutel staat klopt en dat je die persoon vertrouwd.</p>
<p>Op die manier ontstaat er een web van vertrouwensrelaties. En als jij Tony vertrouwd, en Tony vertrouwd Steve. Dan kan je indirect ervan uitgaan dat de naam van de sleutel van Steve klopt. Op die manier kan je indirect een hele hoop sleutels vertrouwen. Op onze keyserver zie je bijvoorbeeld <a href="http://sec1.aii.avans.nl:11371/pks/lookup?op=vindex&search=0XB69F77232CE5546445137725D555F2F5FA9E1C5A" target="_blank">wie er allemaal direct onze sleutel vertrouwd.</a></p>
<p>Op die manier ontstaat er een web van vertrouwensrelaties. En als jij Tony vertrouwd, en Tony vertrouwd Steve. Dan
kan je indirect ervan uitgaan dat de naam van de sleutel van Steve klopt. Op die manier kan je indirect een hele
hoop sleutels vertrouwen. Op onze keyserver zie je bijvoorbeeld
<a href="http://websec.paulwagener.nl:11371/pks/lookup?op=vindex&search=0XB69F77232CE5546445137725D555F2F5FA9E1C5A" target="_blank">wie er allemaal direct onze sleutel vertrouwd.</a>
</p>
<img src="static/img/web_of_trust.gif">
<p>Als je je eigen sleutel wil gebruiken om andere sleutels te ondertekenen/vertrouwen doe je dat door eerst een publieke sleutel te downloaden van de keyserver, dan deze lokaal te ondertekenen met je eigen sleutel en vervolgens de publieke sleutel weer opnieuw te versturen naar de keyserver.</p>
<p>Als je je eigen sleutel wil gebruiken om andere sleutels te ondertekenen/vertrouwen doe je dat door eerst een publieke
sleutel te downloaden van de keyserver, dan deze lokaal te ondertekenen met je eigen sleutel en vervolgens de publieke
sleutel weer opnieuw te versturen naar de keyserver.</p>
<div class="question">
<span class="question-string">Gebruik je eigen sleutel om onze sleutel (sleutel-ID: B69F77232CE5546445137725D555F2F5FA9E1C5A) en de sleutel van drie medestudenten te ondertekenen. Upload je ondertekening terug naar de keyserver. Plak je eigen sleutel-ID als antwoord hier.</span>
<span class="question-string">Gebruik je eigen sleutel om onze sleutel (sleutel-ID: B69F77232CE5546445137725D555F2F5FA9E1C5A) en de sleutel van
drie medestudenten te ondertekenen. Upload je ondertekening terug naar de keyserver. Plak je eigen sleutel-ID als
antwoord hier.</span>
{% include "points.html" with points=answers.answer_encryption_sign_keys.points max="5" %}
<input class="question-input" name="answer_encryption_sign_keys" value="{{ answers.answer_encryption_sign_keys.string }}">
</div>
<p class="hint"><strong>Hint:</strong> Handtekeningen worden pas verstuurd als je de sleutel die je hebt ondertekend weer terugstuurt naar de server.</p>
<p>Heb je de smaak te pakken? Dan kan je je eigen publieke sleutel ook doorsturen naar andere <a href="http://en.wikipedia.org/wiki/Key_server_%28cryptographic%29" target="_blank">keyservers</a> en laten ondertekenen bij hippe <a href="http://en.wikipedia.org/wiki/Key_signing_party" target="_blank">key signing parties</a>.</p>
<a href="http://xkcd.com/364/" target="_blank"><img src="http://imgs.xkcd.com/comics/responsible_behavior.png"></a>
<h3>Laatste opdracht</h3>
<p>Het vak is bijna afgelopen, en we hebben nog één laatste grote opdracht voor je waarbij je kennis van deze week nog een kan toepassen in een programmeerprojectje. Maak een kleine webapplicatie waar een gebruiker de volgende dingen kan invoeren:</p>
<ul>
<li>Een naam</li>
<li>Een geheime tekst</li>
<li>Een wachtwoord</li>
</ul>
<p>Zorg ervoor dat de webapplicatie de geheime tekst versleuteld opslaat zodat als iemand de database steelt het onmogelijk is om de geheime tekst te lezen. Als de gebruiker alleen een naam en het juiste wachtwoord invult krijgt hij zijn originele tekst weer te zien.</p>
<p>Zet de code op GitHub en leg in de README.md kort uit welke technieken, libraries en frameworks je hebt gebruikt. Je mag zelf kiezen welke programmeertaal je gebruikt.</p>
<div class="question">
<span class="question-string">Plak hier de link naar je GitHub project</span>
{% include "points.html" with points=answers.answer_encryption_github_project.points max="25" %}
<input type="url" class="question-input" name="answer_encryption_github_project" value="{{ answers.answer_encryption_github_project.string }}">
</div>
<p class="hint">
<strong>Hint:</strong> Handtekeningen worden pas verstuurd als je de sleutel die je hebt ondertekend weer terugstuurt naar
de server.</p>
<img src="static/img/encryption_project.png" class="screenshot" style="width: 50%">
<p>Heb je de smaak te pakken? Dan kan je je eigen publieke sleutel ook doorsturen naar andere
<a href="http://en.wikipedia.org/wiki/Key_server_%28cryptographic%29" target="_blank">keyservers</a> en laten ondertekenen bij hippe
<a href="http://en.wikipedia.org/wiki/Key_signing_party" target="_blank">key signing parties</a>.</p>
{% endblock %}
<a href="http://xkcd.com/364/" target="_blank">
<img src="http://imgs.xkcd.com/comics/responsible_behavior.png">
</a>

@ -1,29 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/static/css/semantic.min.css">
<style type="text/css">
<head>
<link rel="stylesheet" href="/static/css/semantic.min.css">
<style type="text/css">
body {
margin-top: 20px;
}
</style>
</head>
<body>
<h1 class="ui centered aligned header">Let's Encrypt</h1>
<div class="ui three column centered grid">
<div class="column ui">
<form method="POST" action="" class="ui form primary center aligned segment">
{% csrf_token %}
{% if challenge %}
<p>Vanaf<br>
<a href="http://sec1.aii.avans.nl/.well-known/acme-challenge/{{challenge}}">http://sec1.aii.avans.nl/.well-known/acme-challenge/{{challenge}}</a><br> wordt de komende 10 minuten de volgende tekst getoond:<br>
<code>{{challenge}}.{{response}}</code>
{% elif error %}
</style>
</head>
<body>
<h1 class="ui centered aligned header">Let's Encrypt</h1>
<div class="ui three column centered grid">
<div class="column ui">
<form method="POST" action="" class="ui form primary center aligned segment">
{% csrf_token %} {% if challenge %}
<p>Vanaf
<br>
<a href="http://websec.paulwagener.nl/.well-known/acme-challenge/{{challenge}}">http://websec.paulwagener.nl/.well-known/acme-challenge/{{challenge}}</a>
<br> wordt de komende 10 minuten de volgende tekst getoond:
<br>
<code>{{challenge}}.{{response}}</code> {% elif error %}
<div class="ui negative message">
<p>{{error}}</p>
</div>
@ -34,20 +33,24 @@
<div class="ui huge input">
<textarea name="challenge-response" value="" style="text-align: center;" placeholder=""></textarea>
</div>
<p>Vul hier de code in die Let's Encrypt van je vraagt om te geven via <br><code>http://sec1.aii.avans.nl/.well-known/acme-challenge/</code></p>
<p>Vul hier de code in die Let's Encrypt van je vraagt om te geven via
<br>
<code>http://websec.paulwagener.nl/.well-known/acme-challenge/</code>
</p>
</div>
<button type="submit" class="ui big blue submit button">Opslaan</button>
{% endif %}
</form>
</div>
</form>
</div>
</div>
</div>
</body>
</body>
</html>

@ -1,260 +1,371 @@
{% extends "base.html" %}
{% extends "base.html" %} {% block content %}
<h1>OAuth</h1>
{% block content %}
<h1>OAuth</h1>
<img src="static/img/oauth.png" style="float: right">
<img src="static/img/oauth.png" style="float: right">
<p>Heb je wel eens gebruik gemaakt van een API van Twitter, Facebook of Google? Dan heb je waarschijnlijk te maken gehad
<strong>OAuth</strong>, de technologie die je toestemming verleent om gebruik te maken van die API's.</p>
<p>Er zijn veel misverstanden over OAuth waardoor het vaak verkeerd begrepen wordt en er veel frictie ontstaat ontstaat tussen
de API en de ontwikkelaar. Het is bijvoorbeeld niet ontworpen om enkel mee in te loggen, hoewel het daar wel veel voor
gebruikt wordt. Deze week gaan we kijken naar het probleem van authoriseren en hoe OAuth dat oplost.</p>
<p>We gaan deze week oefenen met OAuth 2.0. Er is ook versie 1.0 en 1.0a die heel anders werken (hoewel ze qua concept wel gelijk
zijn). Let altijd op met welke versie je te maken hebt, je kan een 2.0 client niet laten praten met een 1.0 server en vice
versa.
</p>
<p>We nemen als voorbeeld de Poespas bank. Een simpele website waarmee gebruikers kunnen inloggen met een gebruikersnaam en
wachtwoord. Als ze ingelogd zijn zien ze hun huidige saldo. De bank heeft een simpele API waarmee gebruikers hun saldo
kunnen checken.</p>
<h3>Simpele authenticatie</h3>
<p>Heb je wel eens gebruik gemaakt van een API van Twitter, Facebook of Google? Dan heb je waarschijnlijk te maken gehad <strong>OAuth</strong>, de technologie die je toestemming verleent om gebruik te maken van die API's.</p>
<p>Een simpele manier om de saldo API te implementeren is om rechtstreeks je gebruikersnaam en wachtwoord mee te geven in de
API request. De server checkt of de inloggegevens correct zijn en geeft de saldo informatie van die gebruiker terug. Uiteraard
moet dit alles over een beveiligde verbinding gebeuren, maar als dat zo is is het in theorie een veilige oplossing.</p>
<figure>
<img src="static/img/auth_basic.png">
</figure>
<img src="static/img/http_auth.png" style="float: right; width: 30%; margin-left: 10px">
<p>Veel echte API's werkte vroeger op deze manier (vaak op basis van
<a href="http://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank">HTTP Authentication</a>). En zolang alles over een beveiligde verbinding tussen de gebruiker en de server loopt is alles
veilig. De problemen beginnen echter als een derde partij betrokken raakt bij onze API.</p>
<p>Een startup heeft de
<i>BudgetApp</i> ontwikkelt, een nieuwe app die laat zien hoeveel saldo je per maand op je rekening hebt staan. Ze maken gebruik
van de Poespas API om het saldo van de gebruiker op te halen. Maar om die API te kunnen gebruiken hebben ze de gebruikersnaam
en het wachtwoord van de gebruiker nodig. Op hun inlogscherm vragen ze daarom om de inloggegevens zodat de app goed kan
werken.
</p>
<figure>
<img src="static/img/auth_basic_app.png">
</figure>
<p>Het probleem met deze manier van authenticeren wordt nu snel duidelijk: de app krijgt de gebruikersnaam en wachtwoord van
de gebruiker in handen. Daarmee kunnen ze niet alleen het saldo ophalen met de API. Maar ook alle andere dingen die de
gebruiker kan zoals bijvoorbeeld inloggen, geld overschrijven en het wachtwoord veranderen.</p>
<p>Om deze situatie te voorkomen willen we een authorisatiesysteem waarbij de app wel een sleutel krijgt om de API te gebruiken,
maar niet het wachtwoord van de gebruiker zelf. Dat moet strict geheim blijven.</p>
<h3>Access tokens</h3>
<img src="static/img/access_token.png" class="center-block" style="float: right; width: 25%">
<p>OAuth lost dit probleem op door het concept van een
<b>access token</b>. Een lange string waarmee je aangeeft dat een bepaalde gebruiker jou toestemming heeft gegeven om de API
te mogen gebruiken. Deze token geef je bij elke aanroep van de API mee in een speciale 'Authorization' header, zodat de
server deze kan verifiëren.</p>
<p>De app heeft nu niet meer de gebruikersnaam en wachtwoord van de gebruiker nodig, de access token is voor de bank een veilige
manier om toegang tot de API te geven. En omdat een access token maar tijdelijk geldig is (vaak maar een uur) blijft de
schade relatief beperkt als een hacker hier toegang tot krijgt.</p>
<img src="static/img/oauth_facebook.png" class="center-block">
<p>Access tokens kan je aanvragen door de gebruiker te sturen naar een speciale authorisatie pagina. Je hebt ze vast wel eens
eerder gezien: de pagina's waar je moet inloggen en op 'Geef toestemming' moet klikken. Zodra je op die knop klikt wordt
je weer teruggestuurd naar de oorspronkelijke app of webapplicatie met de access token in de URL.</p>
<figure>
<img src="static/img/auth_access_token.png" class="center-block">
</figure>
<p>Je kan ook een speciale
<b>authorisatie code</b> terugkrijgen in plaats van een access token als je dat in een parameter aanzet. Deze kan je inwisselen
voor een access token en een refresh token, een speciale token waarmee je nieuwe access tokens kan maken. Handig als je
langer dan een uur van de API gebruik wil blijven maken. Met al die verschillende tokens gaan we oefenen in de opdrachten.</p>
<h3>Opdrachten</h3>
<p>Deze site heeft ook een API die te vinden is op:
<a href="/api/hello" target="_blank">/api/hello</a>. Die mag je uiteraard alleen gebruiken als je een access token hebt, als je gewoon op de link klikt krijg
je een lege 403 pagina (Forbidden). We gaan alle stappen doorlopen om te komen tot de almachtige access token waarmee we
de API kunnen aanroepen.</p>
<p>De eerste stap bij een OAuth provider is om een client aan te maken. Daarmee weet de server altijd wie het is die de API
aanroep doet. Voor deze opdracht kan je die aanmaken op
<a href="/o/applications/" target="_blank">deze pagina</a>. Maak je eigen applicatie met de volgende gegevens:</p>
<ul>
<li>
<b>Name</b>: mag je zelf kiezen</li>
<li>
<b>Client id</b>: mag je zelf kiezen, maar moet wel uniek zijn</li>
<li>
<b>Client secret</b>: mag je zelf kiezen</li>
<li>
<b>Client type</b>: Confidential</li>
<li>
<b>Authorization grant type</b>: Implicit</li>
<li>
<b>Redirect uris</b>: http://example.com/ (mag ook een eigen URL zijn)</li>
</ul>
<figure>
<img src="static/img/oauth_register.png" style="width: 50%">
</figure>
<div class="question">
<span class="question-string">Wat is de client_id die je hebt geregistreerd?</span>
{% include "points.html" with points=answers.answer_oauth_client_id.points max="5" %}
<input class="question-input" name="answer_oauth_client_id" value="{{ answers.answer_oauth_client_id.string }}"></input>
</div>
<p>Elke OAuth server heeft twee endpoints (lees: URL's): de authorisatie endpoint en de token endpoint. Hieronder zie je de
endpoints van een aantal bekende servers:</p>
<table border="1" cellpadding="4">
<tr>
<th>Service</th>
<th>Authorization endpoint</th>
<th>Token endpoint</th>
</tr>
<tr>
<td>Deze cursus</td>
<td>http://websec.paulwagener.nl/o/authorize/</td>
<td>http://websec.paulwagener.nl/o/token/</td>
</tr>
<tr>
<td>GitHub</td>
<td>https://github.com/login/oauth/authorize</td>
<td>https://github.com/login/oauth/access_token</td>
</tr>
<tr>
<td>Google</td>
<td>https://accounts.google.com/o/oauth2/auth</td>
<td>https://accounts.google.com/o/oauth2/token</td>
</tr>
<tr>
<td>Facebook</td>
<td>https://www.facebook.com/dialog/oauth</td>
<td>https://graph.facebook.com/oauth/access_token</td>
</tr>
</table>
<p>De authorisatie endpoint is de URL waar je de gebruiker heenstuurt om hem te laten inloggen op de website en om op 'Toestaan'
te laten klikken. Deze site redirect daarna weer terug naar je eigen site / app met een speciale authorisatie code. De
token endpoint is de OAuth API waar we al onze access tokens uit kunnen halen, maar dan hebben we wel eerst die authorisatie
code nodig.</p>
<p>Om te authoriseren hebben we de volgende URL parameters nodig: (
<a href="http://tools.ietf.org/html/rfc6749#section-4.1.1" target="_blank">documentatie</a>)</p>
<ul>
<li>
<b>response_type</b>: "token" of "code". Met "token" krijg je direct een access token in de redirect URL. Handig als je
de API maar 1x hoeft te gebruiken. Minder handig als je de API langer wilt blijven gebruiken, want access tokens blijven
vaak niet langer dan een uur geldig. Dan moet je de gebruiker elk uur opnieuw laten inloggen. Met "code" krijg je een
authorisatie code die je kan inwisselen voor een speciale refresh_token, daar kan je tot in de oneindigheid nieuwe access
tokens mee maken.
<i>Voor deze opdracht gebruiken we "token"</i>.</li>
<li>
<b>client_id</b>: Jouw gekozen client id</li>
<li>
<b>redirect_uri</b>: optioneel, en eigenlijk ook redundant. Want die geef je ook vaak op als je je registreert als client
bij de provider. Als de gebruiker op 'Toestaan' heeft geklikt wordt hij naar deze URL teruggestuurt met de authorisatie
code of access token</li>
<li>
<b>scope</b>: optioneel, kan je mee aangeven welke gedeeltes van de API je wilt kunnen gebruiken</li>
<li>
<b>state</b>: optioneel, een string die je kan meegeven die ook weer wordt teruggestuurd als de gebruiker wordt terug geredirect.
Kan handig zijn.</li>
</ul>
<p>Voor deze site is de authorisatie URL:
<br>
<span class="url">http://websec.paulwagener.nl/o/authorize/?client_id=(CLIENT_ID)&amp;response_type=token</span>
</p>
<div class="question">
<span class="question-string">Authoriseer met je eigen client id. Welke access token heb je gekregen?</span>
{% include "points.html" with points=answers.answer_oauth_implicit_access_token.points max="5" %}
<input class="question-input" name="answer_oauth_implicit_access_token" value="{{ answers.answer_oauth_implicit_access_token.string }}"></input>
</div>
<p class="hint">
<strong>Hint:</strong> Let je wel op dat er een slash staat achter
<code>authorize</code> in de URL?</p>
<div class="question">
<span class="question-string">Hoeveel seconden is deze token code geldig?</span>
{% include "points.html" with points=answers.answer_oauth_implicit_access_token_expires.points max="5" %}
<input class="question-input" name="answer_oauth_implicit_access_token_expires" value="{{ answers.answer_oauth_implicit_access_token_expires.string }}"></input>
</div>
<p>De access token kan je nu gebruiken om een request te doen naar
<a href="/api/hello" target="_blank">/api/hello</a>. De token geef je mee door de volgende HTTP header mee te sturen:</p>
<code class="pre">Authorization: Bearer nW8JkemabiKpxvD1Yen3FCcWM3k7vr</code>
<p>Uiteraard moet je je eigen access token dan gebruiken. Er zijn vele tools waarmee je HTTP requests mee kan maken met je eigen
headers en data. In de screenshots gebruiken we
<a href="https://chrome.google.com/webstore/detail/postman-rest-client-packa/fhbjgbiflinjbdggehcddcbncdddomop" target="_blank">Postman</a>.</p>
<img src="static/img/oauth_call_api.png" class="center-block screenshot" style="width: 80%; margin-top: 20px">
<div class="question">
<span class="question-string">Wat is de geheime code die gestuurd wordt als je de API aanroept?</span>
{% include "points.html" with points=answers.answer_oauth_api_hello.points max="10" %}
<input class="question-input" name="answer_oauth_api_hello" value="{{ answers.answer_oauth_api_hello.string }}"></input>
</div>
<p class="hint">
<strong>Hint:</strong> Let op dat je de Authorization data als
<i>header</i> meestuurt. Via de POST form-data of als URL parameter gaat niet werken!</p>
<h3>Web applicaties</h3>
<p>Wat doen we als de token verloopt en je nog steeds de API wil gebruiken? Je kan natuurlijk de gebruiker opnieuw naar de authorisatie
URL sturen voor een nieuwe access token. Maar als jouw web applicatie dagelijks de gebruiker meerdere keren per dag redirect
om op 'Geef toestemming' te klikken wordt die daar helemaal gek van.</p>
<p>OAuth heeft hier de zogenaamde refresh tokens voor verzonnen. Dit is een uitgebreidere manier om access tokens te krijgen
en is meer geschikt voor webapplicaties. We moeten wel helemaal terug naar het begin en alle stappen net iets anders doen:</p>
<ol>
<li>Ga naar
<a href="/o/applications/" target="_blank">/o/applications/</a> en verander jouw applicatie zodat deze nu als
<b>Authorization grant type</b> de waarde
<b>Authorization code</b> heeft.
<br>
<img src="static/img/oauth_set_grant_type.png" class="screenshot" style="width: 40%">
</li>
<li>Ga opnieuw naar dezelfde authorisatie URL van vorige keer, maar nu met
<b>response_type=code</b> in plaats van response_type=token</li>
<li>Je wordt nu teruggestuurd met een zogenaamde authorisatie code</li>
</ol>
<div class="question">
<span class="question-string">Welke authorisatie code heb je gekregen?</span>
{% include "points.html" with points=answers.answer_oauth_authorization_code.points max="5" %}
<input class="question-input" name="answer_oauth_authorization_code" value="{{ answers.answer_oauth_authorization_code.string }}"></input>
</div>
<img src="static/img/oauth_authorization_code.png" style="width: 25%; float: right">
<p>Deze authorisatie code is nog geen access token op zich, maar kan een webapplicatie wel inwisselen voor een access token.
Dit doet het door een POST request te doen naar de token endpoint. We moeten daarvoor de volgende parameters meesturen:</p>
<ul>
<li>
<b>grant_type</b>: Moet de waarde "authorization_code" hebben.</li>
<li>
<b>code</b>: De authorisatie code die we hebben gekregen van de authorisatie endpoint.</li>
<li>
<b>redirect_uri</b>: Dezelfde URL die we eerder als redirect_uri hebben gebruikt.</li>
<li>
<b>client_id</b>: De client id die je hebt verzonnen</li>
<li>
<b>client_secret</b>: De client secret die je hebt verzonnen</li>
</ul>
<p>Doe er niet te lang over, authorisatie codes verlopen vaak al na enkele minuten. Als je het goed doet krijg je een response
met daarin de refresh_token (en een gratis access_token!). Als je een
<code>invalid_grant</code> error krijgt betekent dat dat jouw code verlopen is en dat je een nieuwe moet aanvragen. Als je een
<code>invalid_client</code> error krijgt moet je goed controleren of je redirect_uri, client_id en client_secret allemaal goed staan ingesteld. En
als je een
<code>access_denied</code> krijgt moet je nog een keer heel goed controleren of je redirect_uri echt
<i>exact</i> hetzelfde is als toen je je app hebt geregistreerd.</code>. Krijg je een andere error? Controleer dan nog een
keer extra goed of de URL eindigt op
<code>/token/</code> (die laatste slash is belangrijk!) en dat je alle data verstuurd als form data via POST.</p>
<img src="static/img/oauth_exchange_auth_code.png" class="screenshot" style="margin: 20px; width: 80%; margin-left: auto; margin-right: auto;">
<div class="question">
<span class="question-string">Copy paste de response die je hebt gekregen waar de refresh token in staat</span>
{% include "points.html" with points=answers.answer_oauth_refresh_token.points max="5" %}
<textarea class="question-input" name="answer_oauth_refresh_token">{{ answers.answer_oauth_refresh_token.string }}</textarea>
</div>
<p>Er zijn veel misverstanden over OAuth waardoor het vaak verkeerd begrepen wordt en er veel frictie ontstaat ontstaat tussen de API en de ontwikkelaar. Het is bijvoorbeeld niet ontworpen om enkel mee in te loggen, hoewel het daar wel veel voor gebruikt wordt. Deze week gaan we kijken naar het probleem van authoriseren en hoe OAuth dat oplost.</p>
<img src="static/img/oauth_refresh_token.png" style="float: right; width: 25%">
<p>Gefeliciteerd, je hebt nu een refresh token! Een oneindige bron van nieuwe access tokens. Je vraagt je bijna af waarom OAuth
uberhaupt de moeite doet om een authorisatie code te hebben als die toch maar zo kort gebruikt wordt. De reden hiervoor
is dat dit mechanisme ervoor zorgt dat alleen de webapplicatie de refresh en access tokens kan ophalen, en niet de gebruiker.
Zonder de juiste client_secret kan de gebruiker namelijk helemaal niets met de authorisatie code.</p>
<p>We schakelen voor het gebruik van de refresh token even over naar een hele andere site</p>
<p>We gaan deze week oefenen met OAuth 2.0. Er is ook versie 1.0 en 1.0a die heel anders werken (hoewel ze qua concept wel gelijk zijn). Let altijd op met welke versie je te maken hebt, je kan een 2.0 client niet laten praten met een 1.0 server en vice versa.</p>
<h3>Google</h3>
<p>We nemen als voorbeeld de Poespas bank. Een simpele website waarmee gebruikers kunnen inloggen met een gebruikersnaam en wachtwoord. Als ze ingelogd zijn zien ze hun huidige saldo. De bank heeft een simpele API waarmee gebruikers hun saldo kunnen checken.</p>
<p>Bij Google hebben we een OAuth client geregistreerd en de volgende gegevens gekregen:</p>
<h3>Simpele authenticatie</h3>
<p>Een simpele manier om de saldo API te implementeren is om rechtstreeks je gebruikersnaam en wachtwoord mee te geven in de API request. De server checkt of de inloggegevens correct zijn en geeft de saldo informatie van die gebruiker terug. Uiteraard moet dit alles over een beveiligde verbinding gebeuren, maar als dat zo is is het in theorie een veilige oplossing.</p>
<figure>
<img src="static/img/auth_basic.png">
</figure>
<img src="static/img/http_auth.png" style="float: right; width: 30%; margin-left: 10px">
<p>Veel echte API's werkte vroeger op deze manier (vaak op basis van <a href="http://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank">HTTP Authentication</a>). En zolang alles over een beveiligde verbinding tussen de gebruiker en de server loopt is alles veilig. De problemen beginnen echter als een derde partij betrokken raakt bij onze API.</p>
<p>Een startup heeft de <i>BudgetApp</i> ontwikkelt, een nieuwe app die laat zien hoeveel saldo je per maand op je rekening hebt staan. Ze maken gebruik van de Poespas API om het saldo van de gebruiker op te halen. Maar om die API te kunnen gebruiken hebben ze de gebruikersnaam en het wachtwoord van de gebruiker nodig. Op hun inlogscherm vragen ze daarom om de inloggegevens zodat de app goed kan werken.</p>
<figure>
<img src="static/img/auth_basic_app.png">
</figure>
<p>Het probleem met deze manier van authenticeren wordt nu snel duidelijk: de app krijgt de gebruikersnaam en wachtwoord van de gebruiker in handen. Daarmee kunnen ze niet alleen het saldo ophalen met de API. Maar ook alle andere dingen die de gebruiker kan zoals bijvoorbeeld inloggen, geld overschrijven en het wachtwoord veranderen.</p>
<p>Om deze situatie te voorkomen willen we een authorisatiesysteem waarbij de app wel een sleutel krijgt om de API te gebruiken, maar niet het wachtwoord van de gebruiker zelf. Dat moet strict geheim blijven.</p>
<h3>Access tokens</h3>
<img src="static/img/access_token.png" class="center-block" style="float: right; width: 25%">
<p>OAuth lost dit probleem op door het concept van een <b>access token</b>. Een lange string waarmee je aangeeft dat een bepaalde gebruiker jou toestemming heeft gegeven om de API te mogen gebruiken. Deze token geef je bij elke aanroep van de API mee in een speciale 'Authorization' header, zodat de server deze kan verifiëren.</p>
<p>De app heeft nu niet meer de gebruikersnaam en wachtwoord van de gebruiker nodig, de access token is voor de bank een veilige manier om toegang tot de API te geven. En omdat een access token maar tijdelijk geldig is (vaak maar een uur) blijft de schade relatief beperkt als een hacker hier toegang tot krijgt.</p>
<img src="static/img/oauth_facebook.png" class="center-block">
<p>Access tokens kan je aanvragen door de gebruiker te sturen naar een speciale authorisatie pagina. Je hebt ze vast wel eens eerder gezien: de pagina's waar je moet inloggen en op 'Geef toestemming' moet klikken. Zodra je op die knop klikt wordt je weer teruggestuurd naar de oorspronkelijke app of webapplicatie met de access token in de URL.</p>
<figure>
<img src="static/img/auth_access_token.png" class="center-block">
</figure>
<p>Je kan ook een speciale <b>authorisatie code</b> terugkrijgen in plaats van een access token als je dat in een parameter aanzet. Deze kan je inwisselen voor een access token en een refresh token, een speciale token waarmee je nieuwe access tokens kan maken. Handig als je langer dan een uur van de API gebruik wil blijven maken. Met al die verschillende tokens gaan we oefenen in de opdrachten.</p>
<h3>Opdrachten</h3>
<p>Deze site heeft ook een API die te vinden is op: <a href="/api/hello" target="_blank">/api/hello</a>. Die mag je uiteraard alleen gebruiken als je een access token hebt, als je gewoon op de link klikt krijg je een lege 403 pagina (Forbidden). We gaan alle stappen doorlopen om te komen tot de almachtige access token waarmee we de API kunnen aanroepen.</p>
<p>De eerste stap bij een OAuth provider is om een client aan te maken. Daarmee weet de server altijd wie het is die de API aanroep doet. Voor deze opdracht kan je die aanmaken op <a href="/o/applications/" target="_blank">deze pagina</a>. Maak je eigen applicatie met de volgende gegevens:</p>
<ul>
<li><b>Name</b>: mag je zelf kiezen</li>
<li><b>Client id</b>: mag je zelf kiezen, maar moet wel uniek zijn</li>
<li><b>Client secret</b>: mag je zelf kiezen</li>
<li><b>Client type</b>: Confidential</li>
<li><b>Authorization grant type</b>: Implicit</li>
<li><b>Redirect uris</b>: http://example.com/ (mag ook een eigen URL zijn)</li>
</ul>
<figure>
<img src="static/img/oauth_register.png" style="width: 50%">
</figure>
<div class="question">
<span class="question-string">Wat is de client_id die je hebt geregistreerd?</span>
{% include "points.html" with points=answers.answer_oauth_client_id.points max="5" %}
<input class="question-input" name="answer_oauth_client_id" value="{{ answers.answer_oauth_client_id.string }}"></input>
</div>
<p>Elke OAuth server heeft twee endpoints (lees: URL's): de authorisatie endpoint en de token endpoint. Hieronder zie je de endpoints van een aantal bekende servers:</p>
<table border="1" cellpadding="4">
<tr>
<th>Service</th>
<th>Authorization endpoint</th>
<th>Token endpoint</th>
</tr>
<tr>
<td>Dit vak</td>
<td>http://sec1.aii.avans.nl/o/authorize/</td>
<td>http://sec1.aii.avans.nl/o/token/</td>
</tr>
<tr>
<td>GitHub</td>
<td>https://github.com/login/oauth/authorize</td>
<td>https://github.com/login/oauth/access_token</td>
</tr>
<tr>
<td>Google</td>
<td>https://accounts.google.com/o/oauth2/auth</td>
<td>https://accounts.google.com/o/oauth2/token</td>
</tr>
<tr>
<td>Facebook</td>
<td>https://www.facebook.com/dialog/oauth</td>
<td>https://graph.facebook.com/oauth/access_token</td>
</tr>
</table>
<p>De authorisatie endpoint is de URL waar je de gebruiker heenstuurt om hem te laten inloggen op de website en om op 'Toestaan' te laten klikken. Deze site redirect daarna weer terug naar je eigen site / app met een speciale authorisatie code. De token endpoint is de OAuth API waar we al onze access tokens uit kunnen halen, maar dan hebben we wel eerst die authorisatie code nodig.</p>
<p>Om te authoriseren hebben we de volgende URL parameters nodig: (<a href="http://tools.ietf.org/html/rfc6749#section-4.1.1" target="_blank">documentatie</a>)</p>
<ul>
<li><b>response_type</b>: "token" of "code". Met "token" krijg je direct een access token in de redirect URL. Handig als je de API maar 1x hoeft te gebruiken. Minder handig als je de API langer wilt blijven gebruiken, want access tokens blijven vaak niet langer dan een uur geldig. Dan moet je de gebruiker elk uur opnieuw laten inloggen. Met "code" krijg je een authorisatie code die je kan inwisselen voor een speciale refresh_token, daar kan je tot in de oneindigheid nieuwe access tokens mee maken. <i>Voor deze opdracht gebruiken we "token"</i>.</li>
<li><b>client_id</b>: Jouw gekozen client id</li>
<li><b>redirect_uri</b>: optioneel, en eigenlijk ook redundant. Want die geef je ook vaak op als je je registreert als client bij de provider. Als de gebruiker op 'Toestaan' heeft geklikt wordt hij naar deze URL teruggestuurt met de authorisatie code of access token</li>
<li><b>scope</b>: optioneel, kan je mee aangeven welke gedeeltes van de API je wilt kunnen gebruiken</li>
<li><b>state</b>: optioneel, een string die je kan meegeven die ook weer wordt teruggestuurd als de gebruiker wordt terug geredirect. Kan handig zijn.</li>
</ul>
<p>Voor deze site is de authorisatie URL:<br>
<span class="url">http://sec1.aii.avans.nl/o/authorize/?client_id=(CLIENT_ID)&amp;response_type=token</span></p>
<div class="question">
<span class="question-string">Authoriseer met je eigen client id. Welke access token heb je gekregen?</span>
{% include "points.html" with points=answers.answer_oauth_implicit_access_token.points max="5" %}
<input class="question-input" name="answer_oauth_implicit_access_token" value="{{ answers.answer_oauth_implicit_access_token.string }}"></input>
</div>
<p class="hint"><strong>Hint:</strong> Let je wel op dat er een slash staat achter <code>authorize</code> in de URL?</p>
<div class="question">
<span class="question-string">Hoeveel seconden is deze token code geldig?</span>
{% include "points.html" with points=answers.answer_oauth_implicit_access_token_expires.points max="5" %}
<input class="question-input" name="answer_oauth_implicit_access_token_expires" value="{{ answers.answer_oauth_implicit_access_token_expires.string }}"></input>
</div>
<p>De access token kan je nu gebruiken om een request te doen naar <a href="/api/hello" target="_blank">/api/hello</a>. De token geef je mee door de volgende HTTP header mee te sturen:</p>
<code class="pre">Authorization: Bearer nW8JkemabiKpxvD1Yen3FCcWM3k7vr</code>
<p>Uiteraard moet je je eigen access token dan gebruiken. Er zijn vele tools waarmee je HTTP requests mee kan maken met je eigen headers en data. In de screenshots gebruiken we <a href="https://chrome.google.com/webstore/detail/postman-rest-client-packa/fhbjgbiflinjbdggehcddcbncdddomop" target="_blank">Postman</a>.</p>
<img src="static/img/oauth_call_api.png" class="center-block screenshot" style="width: 80%; margin-top: 20px">
<div class="question">
<span class="question-string">Wat is de geheime code die gestuurd wordt als je de API aanroept?</span>
{% include "points.html" with points=answers.answer_oauth_api_hello.points max="10" %}
<input class="question-input" name="answer_oauth_api_hello" value="{{ answers.answer_oauth_api_hello.string }}"></input>
</div>
<p class="hint"><strong>Hint:</strong> Let op dat je de Authorization data als <i>header</i> meestuurt. Via de POST form-data of als URL parameter gaat niet werken!</p>
<h3>Web applicaties</h3>
<p>Wat doen we als de token verloopt en je nog steeds de API wil gebruiken? Je kan natuurlijk de gebruiker opnieuw naar de authorisatie URL sturen voor een nieuwe access token. Maar als jouw web applicatie dagelijks de gebruiker meerdere keren per dag redirect om op 'Geef toestemming' te klikken wordt die daar helemaal gek van.</p>
<p>OAuth heeft hier de zogenaamde refresh tokens voor verzonnen. Dit is een uitgebreidere manier om access tokens te krijgen en is meer geschikt voor webapplicaties. We moeten wel helemaal terug naar het begin en alle stappen net iets anders doen:</p>
<ol>
<li>Ga naar <a href="/o/applications/" target="_blank">/o/applications/</a> en verander jouw applicatie zodat deze nu als <b>Authorization grant type</b> de waarde <b>Authorization code</b> heeft.<br>
<img src="static/img/oauth_set_grant_type.png" class="screenshot" style="width: 40%">
</li>
<li>Ga opnieuw naar dezelfde authorisatie URL van vorige keer, maar nu met <b>response_type=code</b> in plaats van response_type=token</li>
<li>Je wordt nu teruggestuurd met een zogenaamde authorisatie code</li>
</ol>
<div class="question">
<span class="question-string">Welke authorisatie code heb je gekregen?</span>
{% include "points.html" with points=answers.answer_oauth_authorization_code.points max="5" %}
<input class="question-input" name="answer_oauth_authorization_code" value="{{ answers.answer_oauth_authorization_code.string }}"></input>
</div>
<img src="static/img/oauth_authorization_code.png" style="width: 25%; float: right">
<p>Deze authorisatie code is nog geen access token op zich, maar kan een webapplicatie wel inwisselen voor een access token. Dit doet het door een POST request te doen naar de token endpoint. We moeten daarvoor de volgende parameters meesturen:</p>
<ul>
<li><b>grant_type</b>: Moet de waarde "authorization_code" hebben.</li>
<li><b>code</b>: De authorisatie code die we hebben gekregen van de authorisatie endpoint.</li>
<li><b>redirect_uri</b>: Dezelfde URL die we eerder als redirect_uri hebben gebruikt.</li>
<li><b>client_id</b>: De client id die je hebt verzonnen</li>
<li><b>client_secret</b>: De client secret die je hebt verzonnen</li>
</ul>
<p>Doe er niet te lang over, authorisatie codes verlopen vaak al na enkele minuten. Als je het goed doet krijg je een response met daarin de refresh_token (en een gratis access_token!). Als je een <code>invalid_grant</code> error krijgt betekent dat dat jouw code verlopen is en dat je een nieuwe moet aanvragen. Als je een <code>invalid_client</code> error krijgt moet je goed controleren of je redirect_uri, client_id en client_secret allemaal goed staan ingesteld. En als je een <code>access_denied</code> krijgt moet je nog een keer heel goed controleren of je redirect_uri echt <i>exact</i> hetzelfde is als toen je je app hebt geregistreerd.</code>. Krijg je een andere error? Controleer dan nog een keer extra goed of de URL eindigt op <code>/token/</code> (die laatste slash is belangrijk!) en dat je alle data verstuurd als form data via POST.</p>
<img src="static/img/oauth_exchange_auth_code.png" class="screenshot" style="margin: 20px; width: 80%; margin-left: auto; margin-right: auto;">
<div class="question">
<span class="question-string">Copy paste de response die je hebt gekregen waar de refresh token in staat</span>
{% include "points.html" with points=answers.answer_oauth_refresh_token.points max="5" %}
<textarea class="question-input" name="answer_oauth_refresh_token">{{ answers.answer_oauth_refresh_token.string }}</textarea>
</div>
<img src="static/img/oauth_refresh_token.png" style="float: right; width: 25%">
<p>Gefeliciteerd, je hebt nu een refresh token! Een oneindige bron van nieuwe access tokens. Je vraagt je bijna af waarom OAuth uberhaupt de moeite doet om een authorisatie code te hebben als die toch maar zo kort gebruikt wordt. De reden hiervoor is dat dit mechanisme ervoor zorgt dat alleen de webapplicatie de refresh en access tokens kan ophalen, en niet de gebruiker. Zonder de juiste client_secret kan de gebruiker namelijk helemaal niets met de authorisatie code.</p>
<p>We schakelen voor het gebruik van de refresh token even over naar een hele andere site</p>
<h3>Google</h3>
<p>Bij Google hebben we een OAuth client geregistreerd en de volgende gegevens gekregen:</p>
<code style="display: block;">
<code style="display: block;">
Client id: 799427728270-ahr6bg713mtkh2htskbmqko8hpheq1md.apps.googleusercontent.com<br>
Client secret: 3W9FcQefBmhX7CT1FgzqiCdR<br>
Refresh token: 1/WfdEEjWgj5Lm8p6wZzoTCeirQz7e4hMDIxvOkdvSjsU<br></code>
<p>Met deze gegevens kunnen we weer een POST doen naar de token endpoint (voor Google: https://accounts.google.com/o/oauth2/token) om een access token te genereren. Dit keer hoeven we geen redirect_uri mee te sturen en moeten we de grant_type parameter op 'refresh_token' zetten:</p>
<p>Met deze gegevens kunnen we weer een POST doen naar de token endpoint (voor Google: https://accounts.google.com/o/oauth2/token)
om een access token te genereren. Dit keer hoeven we geen redirect_uri mee te sturen en moeten we de grant_type parameter
op 'refresh_token' zetten:</p>
<p class="hint"><strong>Hint:</strong> Deze keer geen slash achteraan de token URL endpoint, goed opletten!</p>
<p class="hint">
<strong>Hint:</strong> Deze keer geen slash achteraan de token URL endpoint, goed opletten!</p>
<img src="static/img/oauth_google_refresh.png" class="screenshot" style="width: 70%; margin: 20px; display: block">
<img src="static/img/oauth_google_refresh.png" class="screenshot" style="width: 70%; margin: 20px; display: block">
<p>Gebruik de access token die je krijgt om een API call te doen naar <span class="url">https://www.googleapis.com/calendar/v3/calendars/secavans@gmail.com/events</span>. Vergeet niet weer de juiste Authorization header te gebruiken om je access token in te zetten! Als je het goed doet krijg je alle events uit onze Google Calender te zien in JSON formaat.</p>
<p>Gebruik de access token die je krijgt om een API call te doen naar
<span class="url">https://www.googleapis.com/calendar/v3/calendars/websecpaulwagener@gmail.com/events</span>. Vergeet niet weer de juiste
Authorization header te gebruiken om je access token in te zetten! Als je het goed doet krijg je alle events uit onze Google
Calender te zien in JSON formaat.</p>
<img src="static/img/oauth_google_call_api.png" class="screenshot" style="width: 70%; margin: 20px; display: block">
<img src="static/img/oauth_google_call_api.png" class="screenshot" style="width: 70%; margin: 20px; display: block">
<div class="question">
<span class="question-string">Wat is de code die in de Geheime afspraak staat? </span>
{% include "points.html" with points=answers.answer_oauth_calendar_secret_code.points max="10" %}
<input class="question-input" name="answer_oauth_calendar_secret_code" value="{{ answers.answer_oauth_calendar_secret_code.string }}"></input>
</div>
<div class="question">
<span class="question-string">Wat is de code die in de Geheime afspraak staat? </span>
{% include "points.html" with points=answers.answer_oauth_calendar_secret_code.points max="10" %}
<input class="question-input" name="answer_oauth_calendar_secret_code" value="{{ answers.answer_oauth_calendar_secret_code.string }}"></input>
</div>
<p>Genoeg tutorial, tijd voor het echte werk! We gaan handmatig het hele OAuth proces doorlopen voor een Google API. Dat mag weer de <a href="https://developers.google.com/google-apps/calendar/v3/reference/events/list" target="_blank">Google Calendar API</a> zijn maar dan voor je eigen Google Calendar. Maar je mag ook een <a href="https://developers.google.com/apis-explorer/" target="_blank">andere API</a> kiezen zoals <a href="https://developers.google.com/gmail/api/" target="_blank">Gmail</a> of <a href="https://developers.google.com/drive/v2/reference/" target="_blank">Google Drive</a>.</p>
<p>Genoeg tutorial, tijd voor het echte werk! We gaan handmatig het hele OAuth proces doorlopen voor een Google API. Dat mag
weer de
<a href="https://developers.google.com/google-apps/calendar/v3/reference/events/list" target="_blank">Google Calendar API</a> zijn maar dan voor je eigen Google Calendar. Maar je mag ook een
<a href="https://developers.google.com/apis-explorer/" target="_blank">andere API</a> kiezen zoals
<a href="https://developers.google.com/gmail/api/" target="_blank">Gmail</a> of
<a href="https://developers.google.com/drive/v2/reference/" target="_blank">Google Drive</a>.</p>
<p>Details over Google OAuth 2.0 kan je vinden op <a href="https://developers.google.com/identity/protocols/OAuth2" target="_blank">deze pagina</a>. Let op dat je API's eerst moet activeren in de <a href="http://console.developers.google.com/" target="_blank">Developer Console</a>. Dat is ook de plek waar je je Client ID en Client secret krijgt, die maak je aan onder APIs &amp; auth > Credentials. Maak een nieuwe client aan voor een standaard web applicatie.</p>
<p>Details over Google OAuth 2.0 kan je vinden op
<a href="https://developers.google.com/identity/protocols/OAuth2" target="_blank">deze pagina</a>. Let op dat je API's eerst moet activeren in de
<a href="http://console.developers.google.com/" target="_blank">Developer Console</a>. Dat is ook de plek waar je je Client ID en Client secret krijgt, die maak je aan onder APIs &amp;
auth > Credentials. Maak een nieuwe client aan voor een standaard web applicatie.</p>
<p>Gebruik de authorisatie URL zoals die <a href="https://developers.google.com/identity/protocols/OAuth2WebServer#formingtheurl" target="_blank">hier</a> staat gedocumenteerd.</p>
<p>Gebruik de authorisatie URL zoals die
<a href="https://developers.google.com/identity/protocols/OAuth2WebServer#formingtheurl" target="_blank">hier</a> staat gedocumenteerd.</p>
<p class="hint"><strong>Hint: </strong>Vergeet niet de juiste scope te gebruiken zodat de gebruiker ook echt toestemming kan geven voor een bepaalde API. Bij Google zijn de scopes meestal URL's. Voor Google Calendar kan je de scope bijvoorbeeld <a href="https://developers.google.com/google-apps/calendar/auth">hier</a> vinden</p>
<p class="hint">
<strong>Hint: </strong>Vergeet niet de juiste scope te gebruiken zodat de gebruiker ook echt toestemming kan geven voor een bepaalde
API. Bij Google zijn de scopes meestal URL's. Voor Google Calendar kan je de scope bijvoorbeeld
<a href="https://developers.google.com/google-apps/calendar/auth">hier</a> vinden</p>
<div class="question">
<span class="question-string">Beschrijf de HTTP requests die je hebt gemaakt om de token te krijgen EN de API te gebruiken (en ook de uitkomst van die requests). Gevoelige data mag je met ***** censureren.</span>
{% include "points.html" with points=answers.answer_oauth_google_requests.points max="15" %}
<textarea class="question-input" name="answer_oauth_google_requests" style="height: 200px">{{ answers.answer_oauth_google_requests.string }}</textarea>
</div>
<div class="question">
<span class="question-string">Beschrijf de HTTP requests die je hebt gemaakt om de token te krijgen EN de API te gebruiken (en ook de uitkomst van die
requests). Gevoelige data mag je met ***** censureren.</span>
{% include "points.html" with points=answers.answer_oauth_google_requests.points max="15" %}
<textarea class="question-input" name="answer_oauth_google_requests" style="height: 200px">{{ answers.answer_oauth_google_requests.string }}</textarea>
</div>
<h3>Mini webapp</h3>
<h3>Mini webapp</h3>
<p>Maak een kleine webapplicatie in PHP of JavaScript waarmee je de requests uit de vorige opdracht automatisch uitvoert (je mag ook een OAuth framework gebruiken)</p>
<p>Maak een kleine webapplicatie in PHP of JavaScript waarmee je de requests uit de vorige opdracht automatisch uitvoert (je
mag ook een OAuth framework gebruiken)</p>
<img src="static/img/webapp1.png" class="screenshot" style="width: 40%">
<img src="static/img/webapp2.png" class="screenshot" style="width: 40%">
<img src="static/img/webapp1.png" class="screenshot" style="width: 40%">
<img src="static/img/webapp2.png" class="screenshot" style="width: 40%">
<div class="question">
<span class="question-string">Plak de broncode van je webapplicatie in het tekstvak</span>
{% include "points.html" with points=answers.answer_oauth_web_app.points max="20" %}
<textarea class="question-input" name="answer_oauth_web_app" style="height: 200px">{{ answers.answer_oauth_web_app.string }}</textarea>
</div>
<div class="question">
<span class="question-string">Plak de broncode van je webapplicatie in het tekstvak</span>
{% include "points.html" with points=answers.answer_oauth_web_app.points max="20" %}
<textarea class="question-input" name="answer_oauth_web_app" style="height: 200px">{{ answers.answer_oauth_web_app.string }}</textarea>
</div>
{% endblock %}

@ -134,7 +134,7 @@
De code beschouwt een gebruiker als ingelogd als de query een rij uit de gebruikerstabel teruggeeft. Manipuleer de query
zodat deze de gegevens van Alice teruggeeft, zonder dat je het wachtwoord hoeft te weten.</p>
<img src="/static/img/poespas.png" style="width: 70%" class="center-block">
<img src="/static/img/poespas.png" style="width: 70%" class="center-block screenshot">
<div class="question">
<span class="question-string">Hoeveel geld heeft Alice op haar rekening staan?</span>
@ -193,7 +193,8 @@
<div class="question">
<span class="question-string">Wat zijn de gebruikersnamen en wachtwoorden van de 4 gebruikers in de database? (de id's van de gebruikers zijn 1,2,3 en
4)</span>
4)
</span>
</div>
<div class="question">

@ -39,7 +39,9 @@ body {
}
.question {
margin: 3em;
padding: 1em;
margin: 2em;
border-left: 3px solid darkorange;
}
.question-string {

@ -62,6 +62,8 @@ $(function () {
var page = getPage(window.location.href);
if (page !== '') {
loadPage(page);
} else {
loadPage('sql');
}
});
Loading…
Cancel
Save