OpenSSL exercises

Paul Wagener 11 years ago
parent 6c6546d875
commit cb88a65b6a
  1. 1
      securityquiz/urls.py
  2. 14
      static/css/style.css
  3. 2
      static/geheim.aes256
  4. BIN
      static/img/certificaat.png
  5. BIN
      static/img/certificaat_rabo.png
  6. BIN
      static/img/encryptie.jpg
  7. BIN
      static/img/publicprivatekey.png
  8. BIN
      static/img/signature.jpg
  9. 1
      templates/base.html
  10. 136
      templates/openssl.html
  11. 6
      templates/sign.html
  12. 87
      views.py

@ -9,5 +9,6 @@ urlpatterns = patterns('',
url(r'^logout$', 'views.avans_logout'), url(r'^logout$', 'views.avans_logout'),
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
url(r'^save$', 'views.save'), url(r'^save$', 'views.save'),
url(r'^sign$', 'views.sign'),
url(r'^(.*)$', 'views.home', name='home'), url(r'^(.*)$', 'views.home', name='home'),
) )

@ -31,3 +31,17 @@ textarea {
input { input {
width: 75%; width: 75%;
} }
code.terminal {
background-color: black;
color: white;
font-family: Courier, monospace;
padding: 1em;
margin: 1em;
display: block;
}
.argument {
font-family: Courier, monospace;
font-weight: bold;
}

@ -0,0 +1,2 @@
U2FsdGVkX1/pLVFH6l/MyI0c/TvaWcMSVv8VnIiy3MbQ45xuvW5CFMAwYsq2slxk
5jor+8OZQz3gnhO031EYpA==

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -21,6 +21,7 @@
<li><a href="/xss">Cross-site Scripting</a></li> <li><a href="/xss">Cross-site Scripting</a></li>
<li><a href="/path">Insecure Direct Object References</a></li> <li><a href="/path">Insecure Direct Object References</a></li>
<li><a href="/wachtwoorden">Wachtwoorden</a></li> <li><a href="/wachtwoorden">Wachtwoorden</a></li>
<li><a href="/openssl">Encryptie &amp; certificaten</a></li>
<li><a href="/bonus">Bonus</a></li> <li><a href="/bonus">Bonus</a></li>
</ul> </ul>

@ -0,0 +1,136 @@
{% extends "base.html" %}
{% block content %}
<h1>Encryptie &amp; Certificaten</h1>
<p>Deze week gaan we aan de slag met het versleutelen en ontsleutelen van gegevens. 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">zoekt op het internet</a> vindt je verschillende mogelijkheden om dat te doen. Bijvoorbeeld de v.1.0.1g Light versie op <a href="http://slproweb.com/products/Win32OpenSSL.html">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>
<h2>Bestandjes ontsleutelen</h2>
<p>Eerst gaan we eens kijken hoe we OpenSSL kunnen gebruiken om data op een veilige manier op te slaan en weer terug te halen. Onderstaand commando kan een versleuteld berichtje weer terug 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">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.">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">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">bestandje</a> wat hij met aes-256-cbc heeft versleuteld. Helaas voor hem heeft hij een niet zo heel sterk wachtwoord 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>
<div class="points"><span class="question-points">10</span> punten</div>
<input class="question-input" name="answer_openssl_decrypt" value="{{ answers.answer_openssl_decrypt }}"></input>
</div>
<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>
<div class="points"><span class="question-points">10</span> punten</div>
<textarea class="question-input" name="answer_openssl_encrypt">{{ answers.answer_openssl_encrypt }}</textarea>
</div>
<p class="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>Certificaten</h2>
<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 -newkey rsa:2048 -nodes -keyout sleutel.pem -out certificaat.pem -days XXX</code>
<p>Dit commando doet een paar dingen tegelijk waar we later op terugkomen. Nadat je de gevraagde informatie hebt ingevuld staat er in het bestand certificaat.pem jouw certificaat. Met dit commando kan je je nieuwe certificaat bewonderen:</p>
<code class="terminal">openssl x509 -text -in certificaat.pem</code>
<div class="question">
<span class="question-string">Kopieer/plak de inhoud van certificaat.pem (begint met <code>-----BEGIN CERTIFICATE-----</code>)</span>
<div class="points"><span class="question-points">10</span> punten</div>
<textarea class="question-input" name="answer_openssl_selfsigned_certificate">{{ answers.answer_openssl_selfsigned_certificate }}</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 identiteiten 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>
<div class="question">
<span class="question-string">Bekijk het certificaat van <a href="https://facebook.com/">Facebook</a>, welk bedrijf heeft dit certificaat verstrekt?</span>
<div class="points"><span class="question-points">5</span> punten</div>
<input class="question-input" name="answer_openssl_facebook_issuer" value="{{ answers.answer_openssl_facebook_issuer }}">
</div>
<p class="hint">Hint: Het certificaat kan je in alle browsers bekijken door op het slot-ikoontje te klikken</p>
<hr>
<div class="alert alert-info">Onderstaande is wat technische achtergrondinfo. Als je alleen de vragen wilt maken kan je overslaan tot <a href="#skip">hier</a></div>
<p>Om te voorkomen dat het het wilde westen wordt en iedereen invult in zo'n certificaat wat hij of zij maar wilt, gebruiken we <a href="http://en.wikipedia.org/wiki/Public-key_cryptography">Public-key cryptografie</a>. Weet je het nog? Dat zijn die twee sleutels, waarvan als de een iets versleuteld, je het resultaat alleen nog maar kan ontsleutelen met de andere sleutel. Een van de sleutels gooi je de wijde wereld in en vertel je tegen iedereen. De andere behoud je op de veiligste plek die je maar kan bedenken.</p>
<img src="/static/img/publicprivatekey.png" class="center-block">
<p>Als je een certificaat wilt verstrekken heb je ook altijd een public en een private key nodig. De public key geef je aan al je vrienden zodat ze weten dat jij het bent als ze die public key tegenkomen. Deze staat ook op het certificaat zelf. De bijbehorende private key gebruik je om (de hash van) het certificaat zelf te versleutelen. Dit voeg je dan toe aan het certificaat als <em>handtekening</em> (signature).</p>
<p>Als iemand het certificaat wilt controleren neemt hij of zij die handtekening en ontsleuteld die weer met de public key. Die vergelijk je vervolgens met het certificaat. Als dat overeenkomt kan je concluderen dat de verstrekker het certificaat zoals jij het ziet heeft ondertekend. Want hij is de enige die in het bezit is van de private key waarmee de handtekening in de eerste plaats gemaakt kon worden.
<hr>
<img src="/static/img/signature.jpg" class="center-block" style="width: 40%">
<h2>Mag ik uw handtekening?</h2>
<a name="skip"></a>
<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.pem -signkey sleutel.pem -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">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>
<div class="points"><span class="question-points">5</span> punten</div>
<input class="question-input" name="answer_openssl_site_issuer" value="{{ answers.answer_openssl_site_issuer }}">
</div>
<div class="question">
<span class="question-string">Plak jouw ondertekende certificaat in onderstaand tekstveld (begint met <code>-----BEGIN CERTIFICATE-----</code>)</span>
<div class="points"><span class="question-points">10</span> punten</div>
<textarea class="question-input" name="answer_openssl_signed_cert">{{ answers.answer_openssl_signed_cert }}</textarea>
</div>
{% endblock %}

@ -0,0 +1,6 @@
<h1>Upload hier je certificate signing request (.csr):</h1>
<form enctype="multipart/form-data" method="POST">
{% csrf_token %}
<input type="file" name="csr">
<input type="submit">
</form>

@ -102,9 +102,96 @@ def home(request, url):
template = 'path.html' template = 'path.html'
elif url == 'wachtwoorden': elif url == 'wachtwoorden':
template = 'wachtwoorden.html' template = 'wachtwoorden.html'
elif url == 'openssl':
template = 'openssl.html'
elif url == 'bonus': elif url == 'bonus':
template = 'bonus.html' template = 'bonus.html'
else: else:
return HttpResponseNotFound('404') return HttpResponseNotFound('404')
return render(request, template, {'answers': answers_dict}) return render(request, template, {'answers': answers_dict})
def sign(request):
if request.method == 'POST':
from OpenSSL import crypto
import time
ca_cert_file = """-----BEGIN CERTIFICATE-----
MIIFDDCCA/SgAwIBAgIJANgaua7fGCcBMA0GCSqGSIb3DQEBBQUAMIG0MQswCQYD
VQQGEwJVUzEWMBQGA1UECBMNV2FzaGluZ3RvbiBEQzETMBEGA1UEBxMKV2FzaGlu
Z3RvbjEhMB8GA1UEChMYVW5pdGVkIFN0YXRlcyBHb3Zlcm5tZW50MRgwFgYDVQQL
Ew9UaGUgV2hpdGUgSG91c2UxFTATBgNVBAMTDEJhcmFjayBPYmFtYTEkMCIGCSqG
SIb3DQEJARYVYmFyYWNrQHdoaXRlaG91c2UuZ292MB4XDTE0MDUyMTA3MjkxM1oX
DTE0MDYyMDA3MjkxM1owgbQxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1XYXNoaW5n
dG9uIERDMRMwEQYDVQQHEwpXYXNoaW5ndG9uMSEwHwYDVQQKExhVbml0ZWQgU3Rh
dGVzIEdvdmVybm1lbnQxGDAWBgNVBAsTD1RoZSBXaGl0ZSBIb3VzZTEVMBMGA1UE
AxMMQmFyYWNrIE9iYW1hMSQwIgYJKoZIhvcNAQkBFhViYXJhY2tAd2hpdGVob3Vz
ZS5nb3YwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6Lqnt0bLHvJAb
LOVR4FEhLgAf4jT/MiJ/Oe8Hbo5Z1LaA/6bcAm8UDYdzlg+NcWyuZv1Pwm5BWSpK
T6z394a4kYUSs/Kwq+HAY8SPt1AZUx4cD0p4D8PAYKDLYAv1PwvMIOnpIscSIrhO
Znug5RGC5B+1flarKBedcCQ744Xrt2FJN4zwUJXSPg1BUHs36Q6tfZyjH2rai8xY
q/kmkFwxj/Hsax7nCS8VALOBB2drySTMQMpLDt3t604xIKvO4oLOPo/KkxxiHgNm
FM0V4aSY1URKBT/4a98YU4rbYe9HsicN2b23VdDOJNpR3xoBnqcDeUmeOyr+u9yC
xMfmWAO9AgMBAAGjggEdMIIBGTAdBgNVHQ4EFgQUHQ/Wns26nFHViXFiQPoJdHAh
/YYwgekGA1UdIwSB4TCB3oAUHQ/Wns26nFHViXFiQPoJdHAh/YahgbqkgbcwgbQx
CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1XYXNoaW5ndG9uIERDMRMwEQYDVQQHEwpX
YXNoaW5ndG9uMSEwHwYDVQQKExhVbml0ZWQgU3RhdGVzIEdvdmVybm1lbnQxGDAW
BgNVBAsTD1RoZSBXaGl0ZSBIb3VzZTEVMBMGA1UEAxMMQmFyYWNrIE9iYW1hMSQw
IgYJKoZIhvcNAQkBFhViYXJhY2tAd2hpdGVob3VzZS5nb3aCCQDYGrmu3xgnATAM
BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAsPNGb/voHkeLEb4xjVw0d
ezdajGxxhf+b3fRZecDuyoNS/cKwpfOtoEPo9PmnCYOLqZiFVkH2zgfAjVRZXWQw
/v3T8JtidGZzRXCmElZO8NEzflfhVa8qc/CRpmQ1SQhLjcTU8XJD02uMf7LS3pzj
CqHy+aX3fHbotHlqB1nkFZwoiAdTX5z7e4znsV9iElHEXjVtGVpbQRxe45IN2yhC
w2m6uzir1Ozsm6cpsxxygziZluz8t7QDyyfi8GkDtdk4joLKsAeawwxjm4JlDi96
jluZ6JUN8TeifPsCWsee5U3XtykclfVDw7DyfgEq9xGFBFoI1wuUfUxmoszGgTvc
-----END CERTIFICATE-----
"""
ca_key_file = """-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAui6p7dGyx7yQGyzlUeBRIS4AH+I0/zIifznvB26OWdS2gP+m
3AJvFA2Hc5YPjXFsrmb9T8JuQVkqSk+s9/eGuJGFErPysKvhwGPEj7dQGVMeHA9K
eA/DwGCgy2AL9T8LzCDp6SLHEiK4TmZ7oOURguQftX5WqygXnXAkO+OF67dhSTeM
8FCV0j4NQVB7N+kOrX2cox9q2ovMWKv5JpBcMY/x7Gse5wkvFQCzgQdna8kkzEDK
Sw7d7etOMSCrzuKCzj6PypMcYh4DZhTNFeGkmNVESgU/+GvfGFOK22HvR7InDdm9
t1XQziTaUd8aAZ6nA3lJnjsq/rvcgsTH5lgDvQIDAQABAoIBAFgRKqAryP1h3Gh+
XBrWmImxUK3EOn1cIaU8qixBx2QGki2CwFLhc9lwbNnn6YNmW5pDbR8FQVH382Ej
PxYsJ7W2X9Pw+qNHKonup1OzylewUVXEhd0018tv6Z9J114ybEoqZ3q30KJrefLb
1y7MK/RWJAmdsTFUzZbTLNCHVxmf3gL05K/H0USY19+sO2GkhHIU9dYrafywAlPh
iFuZAvcVIUDhKsowslBYD3+R5yamN6bvWy8E1IbOBM76nMQKcJlpQv7T+mCJUWhW
71niSoXS8AoxEgbJftZtfqo5Cp5ZenAMUaje4QqjLcqvda41baU3uAIAdadgt/oq
lVl+EaECgYEA2qWLoBYH87xd0MMeYPznDH3Na041c4DNmA5ZT2aaDn88+to9dyrR
Ur052VOz6zMnHd4MWlUvaTpEjUKsxENLwajI8PtQVlB1Kio8Mn5rMdW/A1NUDeDm
db8OTLYxGWw3ug/m6/p7xTepHvJHWAJh4I9iNA+jYZkc3ppWDEbOJfMCgYEA2f1M
EYvDCsLhpx3n4wSjOMRjS1XUGPn/v5aYdVF9rnr2E1zxgZaZRMhD2P2umUj4+2SI
2a1Ve99uXuqgM+1OC5G5TNKje3HikqnGTnqDS2L76WLDuZdkmNmIMKuibSZteHl/
2llrkdGCmV4pfjvszilCxph/rQ5+0uBJFIMrK48CgYEAztD+ZJvSQ8vulbSqvKUc
S+WHdDPTPYEdd/JCqmdr28ChRss+jsUSoQfae2bAbf7Bxm+uEZg4M3npNBFYaIEb
XICyKbgegrayTQMMU9revJHpj1S30jTk6YWiGg/QG7MQd0/pZ1dU0fTXZS1ZLLd8
K7SU+Je+PGhfNXSZZh1ni98CgYArbiS2pjLAtR0CD5pAh48BY1cpDjuIkl5azGUp
kofIuGTIbM8M83Ur1/50f+5GSdyZMWl2fOs4F8bEkFhEoDXZZjoVzS2XDZSHhd2l
ixEXduwbjnrSQhBfx48zqy5cMrjCtOo9FW2yCpzLc5Auvz+pv1y3dnCRiP7Jgrfs
p0l1jwKBgQCYUOEr7FlXMas0KVXzvR4bg1c6pEuORhkdP3w/IO+88RflPe/or1c6
M15u8GjRELX7QyUx5x3fPnYDVPJ97FDqjhHcSiq8Tu8bvFsoBxyZu1EfbMY+ndB7
ojEMEyKAGuYrWFU0GvmNGYeIOdl7Xc7hYgU5m9VzovCV7rs3CIy3xQ==
-----END RSA PRIVATE KEY-----
"""
csr = crypto.load_certificate_request(crypto.FILETYPE_PEM, request.FILES['csr'].read())
ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca_cert_file)
ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key_file)
signed_cert = crypto.X509()
signed_cert.set_serial_number(1)
signed_cert.gmtime_adj_notBefore(0)
signed_cert.gmtime_adj_notAfter(60 * 60 * 24 * 365 * 5)
signed_cert.set_issuer(ca_cert.get_subject())
signed_cert.set_subject(csr.get_subject())
signed_cert.set_pubkey(csr.get_pubkey())
signed_cert.sign(ca_key, 'sha1')
response = HttpResponse(crypto.dump_certificate(crypto.FILETYPE_PEM, signed_cert), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=signed-certificaat.pem'
return response
return render(request, 'sign.html')
Loading…
Cancel
Save