Cryptography for newcomers
The hitchhiker's guide to cipher in devs
@m4d_zhttps://talks.m4dz.net/crypto-for-newcomers/en/Any sensitive data must
be transferred and stored
in an encrypted form
We Need Cryptography!
Cryptography is a matter of:
Cryptanalysis
is as old as Encryption!
Fix?
Plain text: ATTACK AT DAWN
Cipher key: LEMONL EM ONLE
Cipher text: LXFOPV EF RNHR
Fix?
No pattern is strong enough to resist to an endless attack
Hashing is
Data Obfuscation
Failed!
from base64 import b64encode
import secrets
import argon2
import hmac
from haslib import sha256
salt = secrets.token_bytes(64)
hash = argon2.low_level.hash_secret_raw('b'*password, salt,
time_cost=1, memory_cost=8, parallelism=1, hash_len=8,
type=argon2.low_level.Type.D)
record = "$argon2$t=1,m=8,p=1$%s%s" % (b64encode(salt), b64encode(hash))
ph = argon2.PasswordHasher()
record = ph.hash(password)
digest = hmac.new(server_key, 'b'*record, digestmod=sha256).digest()
A properly hashed password with
no repetition and a time-controlled execution
decrease the risk of brute-force hacking
How Encryption Works?
Computers aren’t
truly random!
/dev/urandom
accessA symmetric key
must be shared,
which means it could leak
RSA or Eliptic Curves?
RSA
ECC
→ Better rely on ECC when available
Key Wrapping
import secrets
from struct import pack
from Crypto.Cipher import Blowfish
from Crypto.PublicKey import RSA
iv = secrets.randbits(Blowfish.block_size)
plen = Blowfish.block_size - divmod(len(msg), Blowfish.block_size)[1]
padding = [plen]*plen
token = secrets.token_bytes(32)
cipher = Blowfish.new(token, Blowfish.MODE_CBC, iv)
key = RSA.importKey(recipient_key)
encToken = key.public_key.encrypt(token, 32)
wrap = pack(b'---', encToken, iv + cipher.encrypt(msg + pack('b'*plen, *padding)))
import nacl
from nacl.public import PrivateKey, Box
import User
@app.route("/secret/<username>/<nonce>")
def get_secret(username, nonce):
skfile = open("sk_server.key", "r")
skserver = PrivateKey(skfile, nacl.encoding.RawEncoder)
user = User.query.filter_by(username=username).first()
box = Box(skserver, user.pk)
message = b"Never Gonna Give You Up!"
encrypted = box.encrypt(message, nonce)
return encrypted
const _sodium = require('libsodium-wrapper')
(async () => {
await _sodium.ready
const sodium = _sodium
const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES)
await res = fetch(`/secret/${user.name}/${sodium.to_string(nonce)}`)
const encrypted = res.text()
const decrypted = sodium.crypto_box_open_easy(encrypted, nonce, SERVER_PK, user.sk)
const message = sodium.to_string(decrypted)
// Never Gonna Give You Up!
})
A public-key cryptography based API that allow
passwordless authentication on platforms
@app.route('/webauthn_begin_activate', methods=['POST'])
def webauthn_begin_activate():
# ...
rp_name = 'localhost'
challenge = util.generate_challenge(32)
make_credential_options = webauthn.WebAuthnMakeCredentialOptions(
challenge, rp_name, RP_ID, ukey, username, display_name,
'https://example.com')
return jsonify(make_credential_options.registration_dict)
@app.route('/webauthn_begin_assertion', methods=['POST'])
def webauthn_begin_assertion():
webauthn_user = webauthn.WebAuthnUser(
user.ukey, user.username, user.display_name, user.icon_url,
user.credential_id, user.pub_key, user.sign_count, user.rp_id)
webauthn_assertion_options = webauthn.WebAuthnAssertionOptions(
webauthn_user, challenge)
return jsonify(webauthn_assertion_options.assertion_dict)
@app.route('/verify_assertion', methods=['POST'])
def verify_assertion():
# ...
webauthn_user = webauthn.WebAuthnUser(
user.ukey, user.username, user.display_name, user.icon_url,
user.credential_id, user.pub_key, user.sign_count, user.rp_id)
webauthn_assertion_response = webauthn.WebAuthnAssertionResponse(
webauthn_user, assertion_response, challenge,
ORIGIN, uv_required=False) # User Verification
try:
sign_count = webauthn_assertion_response.verify()
except Exception as e:
return jsonify({'fail': 'Assertion failed. Error: {}'.format(e)})
Never forget that
Paranoïd Web Dino · Tech Evangelist
https://talks.m4dz.net/crypto-for-newcomers/en/ Available under licence CC BY-SA 4.0
m4dz, CC BY-SA 4.0
Courtesy of Unsplash and Pexels contributors
Powered by Reveal.js
Source code available at
https://git.madslab.net/talks