La Cryptographie en 55' chrono
Petit guide du voyageur en terre du chiffrement
@m4d_zToute donnée sensible doit
être transférée et stockée
de façon chiffrée
Solution ? Cryptographie!
La cryptographie, ça concerne :
La cryptanalyse est aussi
vieille que le chiffrement !
Solution ?
Plain text: ATTACK AT DAWN
Cipher key: LEMONL EM ONLE
Cipher text: LXFOPV EF RNHR
Solution ?
Aucun modèle n’est assez robuste
pour contrer une attaque continue
Le hashage est une technique
d’obfuscation des données
Oups !
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()
Un mot de passe haché avec un sel unique
et un temps d’exécution contrôlé
diminue le risque de pénétration par force brute
Chiffrement ?
Nos machines ne sont pas
vraiment aléatoires
/dev/urandom
Une clef symétrique
doit être échangée,
elle peut donc fuiter
Secret partagé (de Shamir)
RSA ou Courbes elliptiques?
RSA
ECC
→ Utilisez ECC si disponible
Encapsulation de clef
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!
})
API utilisant la cryptographie à clé publique,
permettant une authentification sans mot de passe
@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)})
N’oubliez jamais que la sécurité
https://talks.m4dz.net/crypto-for-newcomers/fr/ Disponible sous 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