{ "cells": [ { "cell_type": "markdown", "id": "funded-sheep", "metadata": {}, "source": [ "# Password Hashing\n", "\n", "Secret keys used to encrypt or sign confidential data have to be chosen from a very large keyspace.\n", "\n", "However, passwords are usually short, human-generated strings, making dictionary attacks practical.\n", "\n", "Password hashing functions derive a secret key of any size from a password and salt.\n", "\n", " - The generated key has the size defined by the application, no matter what the password length is.\n", " - The same password hashed with the same parameters will always produce the same output.\n", " - The same password hashed with different salts will produce different outputs.\n", " - The function deriving a key from a password and salt is CPU intensive and intentionally requires a fair amount of memory. Therefore, it mitigates brute-force attacks by requiring a significant effort to verify each password.\n", " \n", "Common use cases:\n", "\n", " - Password storage, or rather storing what it takes to verify a password without having to store the actual password.\n", " - Deriving a secret key from a password; for example, for disk encryption.\n", " \n", "Sodium's high-level crypto_pwhash_* API currently leverages the Argon2id function on all platforms. This can change at any point in time, but it is guaranteed that a given version of libsodium can verify all hashes produced by all previous versions from any platform. Applications don't have to worry about backward compatibility." ] }, { "cell_type": "code", "execution_count": 1, "id": "3b67cc59-27b4-4641-b246-93f026024df5", "metadata": { "tags": [] }, "outputs": [], "source": [ "%load_ext sql" ] }, { "cell_type": "code", "execution_count": 2, "id": "e09360f1-b3ce-436d-a539-fd66d601b598", "metadata": { "tags": [] }, "outputs": [], "source": [ "%config SqlMagic.feedback=False\n", "%config SqlMagic.displaycon=False\n", "%sql postgresql://postgres@/" ] }, { "cell_type": "code", "execution_count": 3, "id": "730c2c47-62bc-41df-89b6-2a58a042acca", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%sql \n", "CREATE EXTENSION IF NOT EXISTS pgsodium;" ] }, { "cell_type": "markdown", "id": "96e972cb-0148-446e-b231-c84b70d5912f", "metadata": {}, "source": [ "### `crypto_pwhash_saltgen()`" ] }, { "cell_type": "code", "execution_count": 4, "id": "5d02ace1-66c0-4573-9bda-50a9f525672d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'@\\xb0\\x86\\x1c\\xcb9\\xf0\\x03\\xfb\\x91xt\\r\\xad\\xffG'\n" ] } ], "source": [ "salt = %sql select pgsodium.crypto_pwhash_saltgen()\n", "salt = salt[0][0].tobytes()\n", "print(salt)" ] }, { "cell_type": "markdown", "id": "6ab7005a-f2da-4eb9-99ec-3567bb7dc34e", "metadata": {}, "source": [ "### `crypto_pwhash(password bytea, salt bytea)`" ] }, { "cell_type": "code", "execution_count": 5, "id": "246c4015-1a73-4ecc-8d79-8c913f1889bd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b'!\\xd6\\x11\\xab\\xdey\\xdc\\x93.\\xb1a7\\xd8\\xf1Q\\xc7\\xc4f\\xc0\\xc0\\xa0\\x96\\xbe<(\\xa3(\\x87\\x1a\\x11(='\n" ] } ], "source": [ "hash = %sql select pgsodium.crypto_pwhash('Correct Horse Battery Staple', :salt)\n", "hash = hash[0][0].tobytes()\n", "print(hash)" ] }, { "cell_type": "markdown", "id": "32f04cd1-6009-47f8-a41a-786bd0c68187", "metadata": {}, "source": [ "### `crypto_pwhash_str(password bytea)`" ] }, { "cell_type": "code", "execution_count": 6, "id": "0f1b4648-9a2f-42c3-9e01-1ffd13da8f50", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\\x246172676f6e32696424763d3139246d3d3236323134342c743d332c703d312437654669655843796f6f736e734736626c42514856672437726a6f6c6c757058596643557838464f494948745651434268643644486d6738707a446f767934493638000000000000000000000000000000000000000000000000000000000000\n" ] } ], "source": [ "hash = %sql select pgsodium.crypto_pwhash_str('Correct Horse Battery Staple')::text\n", "hash = hash[0][0]\n", "print(hash)" ] }, { "cell_type": "markdown", "id": "5c1dd46d-bb59-40c6-9f30-eea9d170d75b", "metadata": {}, "source": [ "### `crypto_pwhash_str_verify(hash bytea, password bytea)`" ] }, { "cell_type": "code", "execution_count": 7, "id": "656e7158-2472-44d9-adf0-a0cd947215c1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "+--------------------------+\n", "| crypto_pwhash_str_verify |\n", "+--------------------------+\n", "| True |\n", "+--------------------------+\n" ] } ], "source": [ "result = %sql select pgsodium.crypto_pwhash_str_verify((:hash)::bytea, 'Correct Horse Battery Staple')\n", "print(result)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.2" } }, "nbformat": 4, "nbformat_minor": 5 }