{"id":1571,"date":"2023-10-26T23:07:36","date_gmt":"2023-10-26T17:37:36","guid":{"rendered":"https:\/\/geekpython.in\/?p=1571"},"modified":"2024-03-01T17:04:58","modified_gmt":"2024-03-01T11:34:58","slug":"hash-passwords-using-bcrypt-in-python","status":"publish","type":"post","link":"https:\/\/geekpython.in\/hash-passwords-using-bcrypt-in-python","title":{"rendered":"Hash Passwords Using bcrypt Library in Python"},"content":{"rendered":"\n<p>Web-based services and websites store hashed versions of your passwords, which means your actual password isn&#8217;t visible or stored in their database instead a string of fixed-length characters is stored.<\/p>\n\n\n\n<p>Hashing is a security technique used to secure your passwords or texts stored in databases. A hash function is used to generate a string of unique fixed-length characters from the provided password by the user.<\/p>\n\n\n\n<p>Let&#8217;s see how the hashing is done. In this article, you&#8217;ll use the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/pypi.org\/project\/bcrypt\/\">bcrypt<\/a> library to hash the user&#8217;s password and then compare that hashed password to the actual password in Python. You&#8217;ll also learn more about the bcrypt library.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing bcrypt<\/h2>\n\n\n\n<p>Open your terminal window and run the following command to install the <code>bcrypt<\/code> library using <strong><em>pip<\/em><\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >pip install bcrypt<\/pre><\/div>\n\n\n\n<p>Now that the <code>bcrypt<\/code> is installed in your system, the next step is to use it for hashing the user&#8217;s password.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hash Password using bcrypt<\/h2>\n\n\n\n<p>In this section, you&#8217;ll see the functions provided by the <code>bcrypt<\/code> library that will help you generate <strong>salt<\/strong> and <strong>hash<\/strong> values.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import bcrypt\n\n# Password to Hash\nmy_password = b'Sachinfromgeekpython'\n\n# Generating Salt\nsalt = bcrypt.gensalt()\n\n# Hashing Password\nhash_password = bcrypt.hashpw(\n    password=my_password,\n    salt=salt\n)\n\nprint(f\"Actual Password: {my_password.decode('utf-8')}\")\n# Print Hashed Password\nprint(f\"Hashed Password: {hash_password.decode('utf-8')}\")<\/pre><\/div>\n\n\n\n<p>The above code imports the <code>bcrypt<\/code> library for hashing the password. A test password is provided in bytes and is stored inside the <code>my_password<\/code> variable.<\/p>\n\n\n\n<p>The code uses the <code>gensalt()<\/code> function from the <code>bcrypt<\/code> library to generate the salt, a string of characters to enhance security.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The salt is a random and unique string of characters combined with the password before hashing to provide additional security, it will always be unique, if two users have the same password, their hashed passwords will be different.<\/p>\n<\/blockquote>\n\n\n\n<p>Then the actual password (<code>my_password<\/code>) and salt (<code>salt<\/code>) are passed to the <code>hashpw()<\/code> function from the <code>bcrypt<\/code> library to produce the hash value of the actual password.<\/p>\n\n\n\n<p>Finally, the actual and hashed passwords are decoded and printed.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >Actual Password: Sachinfromgeekpython\nHashed Password: $2b$12$RF6JLXecIE4qujuPgTwkC.GN2BsOmGf8Ji10LyquoBaHkHWUWgiAm<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Check Password using bcrypt<\/h2>\n\n\n\n<p>Now that you&#8217;ve hashed the password, the next step is to verify the actual password&#8217;s hash value against the user-provided password.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import bcrypt\n\n# Password to Hash\nmy_password = b'Sachinfromgeekpython'\n\n# Generating Salt\nsalt = bcrypt.gensalt()\n\n# Hashing Password\nhash_password = bcrypt.hashpw(\n    password=my_password,\n    salt=salt\n)\n\n# User-provided Password\nuser_password = b'Sachinfromgeekpython'\n\n# Checking Password\ncheck = bcrypt.checkpw(\n    password=user_password,\n    hashed_password=hash_password\n)\n\n# This will print True or False\nprint(check)\n\n# Verifying the Password\nif check:\n    print(\"Welcome to GeekPython.\")\nelse:\n    print(\"Invalid Credential.\")<\/pre><\/div>\n\n\n\n<p>The above code uses the <code>checkpw()<\/code> function from the <code>bcrypt<\/code> library to check the user-provided password against the hashed password. The hashed password (<code>hash_password<\/code>) and user-provided password (<code>user_password<\/code>) are passed inside the function and the result is stored inside the <code>check<\/code> variable.<\/p>\n\n\n\n<p>Then the code prints the <code>check<\/code> variable to obtain the result. In the end, an <code>if-else<\/code> statement is used to verify the password.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >True\nWelcome to GeekPython.<\/pre><\/div>\n\n\n\n<p><code>True<\/code> in the output above indicates that the hashed password matches the user-provided password, making the first condition true.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hash Password Using KDF (Key Derivation Function)<\/h2>\n\n\n\n<p><strong>KDF<\/strong> (Key Derivation Function) is used to add additional security in password hashing. KDFs are used to derive keys from passwords for authentication purposes while including salt and the number of rounds.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import bcrypt\n\npassword = b'Sachinfromgeekpython'\nsalt = bcrypt.gensalt()\n\n# Using KDF from bcrypt Lib\nkey = bcrypt.kdf(\n    password=password,\n    salt=salt,\n    desired_key_bytes=32,\n    rounds=200\n)\n\n# Print Generated Key\nprint(f\"Key: {key}\")<\/pre><\/div>\n\n\n\n<p>The above code uses the <code>kdf()<\/code> function from the <code>bcrypt<\/code> library to derive a key from the password. The function is passed with four parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>password<\/code>: This parameter is set to the <code>password<\/code> variable which contains a byte string.<\/li>\n\n\n\n<li><code>salt<\/code>: This parameter is set to the <code>salt<\/code> variable that contains a unique and fixed-length salt.<\/li>\n\n\n\n<li><code>desired_key_bytes<\/code>: This parameter is set to <code>32<\/code> which is the desired length of the derived key we want. You can set it to your own desired length.<\/li>\n\n\n\n<li><code>rounds<\/code>: This parameter is set to <code>200<\/code> which is the number of iterations to make the derivation of the key more computationally intense to increase security. The higher the rounds more the security but the more it uses resources and time.<\/li>\n<\/ul>\n\n\n\n<p>Finally, the result stored in the <code>key<\/code> variable is printed.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >Key: b'\\xc4#VW\\x9a\\x16\\xdbG?\\x11\\xa9\\xf7\\xbd\\x88\"7+zxo\\xfe@\\xce\\xab\\x89\\xc3g\\x1c\\xec~\\xbe\\xf7'<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Verifying the Password with KDF<\/h2>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import bcrypt\n\npassword = b'Sachinfromgeekpython'\nsalt = bcrypt.gensalt()\n\n# Using KDF from bcrypt Lib\nkey = bcrypt.kdf(\n    password=password,\n    salt=salt,\n    desired_key_bytes=32,\n    rounds=200\n)\n\n# User-provided Password\nuser_password = b'Sachinfromgeekpython'\n\n# Deriving Key from User-provided Password\nuser_key = bcrypt.kdf(\n    password=user_password,\n    salt=salt,\n    desired_key_bytes=32,\n    rounds=200\n)\n\n# Verifying the Password\nif user_key == key:\n    print(\"Welcome to GeekPython.\")\nelse:\n    print(\"Invalid Credential.\")<\/pre><\/div>\n\n\n\n<p>The code derives the key from the user-provided password (<code>user_password<\/code>) and stores it inside the <code>user_key<\/code> variable.<\/p>\n\n\n\n<p>Then the code verifies the derived keys from the user-provided password (<code>user_key<\/code>) and the actual password (<code>password<\/code>).<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >Welcome to GeekPython.<\/pre><\/div>\n\n\n\n<p>The output indicates that the key derived from the user-provided password matches the key derived from the actual password.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Customizing Salt<\/h2>\n\n\n\n<p>The <code>gensalt()<\/code> function accepts two parameters: <code>rounds<\/code> and <code>prefix<\/code>, which allow you to customize the number of rounds of hashing to apply to the salt and prefix of the salt.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import bcrypt\n\n# Customize Salt\nsalt = bcrypt.gensalt(\n    rounds=30,\n    prefix=b'2a'\n)\n\n# Print Generated Salt\nprint(salt.decode('utf-8'))<\/pre><\/div>\n\n\n\n<p>The above code customizes the salt generation by passing the <code>rounds<\/code> parameter which is set to <code>30<\/code> and the <code>prefix<\/code> parameter which is set to <code>b'2a'<\/code> to the <code>gensalt()<\/code> function.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >$2a$30$5uKaXaXVceqCjmKkPf2mnu<\/pre><\/div>\n\n\n\n<p>You can notice that in the beginning after <code>$<\/code>, above provided <code>2a<\/code> is prefixed, and just after that <code>30<\/code> indicates the number of rounds.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Password hashing prevents exposing the user&#8217;s actual password to the attackers. The hash function, which is simply a mathematical function is used to produce the hash value of the password.<\/p>\n\n\n\n<p>In this article, you&#8217;ve learned to hash the user&#8217;s password using the <code>bcrypt<\/code> library in Python and then check the produced hash value against the user-provided password. Additionally, you&#8217;ve seen the <strong>KDF<\/strong> (Key Derivation Function) that adds additional security for hashing.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83c\udfc6<strong>Other articles you might be interested in if you liked this one<\/strong><\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/convert-bytes-into-string\">Different methods to convert bytes into a string in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/build-websocket-server-and-client-using-python\">Create a WebSocket server and client in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/threading-module-to-create-threads-in-python\">Create multi-threaded Python programs using a threading module<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/practical-examination-of-4-deep-learning-models\">Comparing the accuracies of 4 different pre-trained deep learning models<\/a>?<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/render-images-from-flask\">Upload and display images on the frontend using Flask<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/impact-of-learning-rates-on-ml-and-dl-models\">How does the learning rate affect the ML and DL models<\/a>?<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>That&#8217;s all for now<\/strong><\/p>\n\n\n\n<p><strong>Keep Coding\u270c\u270c<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Web-based services and websites store hashed versions of your passwords, which means your actual password isn&#8217;t visible or stored in their database instead a string of fixed-length characters is stored. Hashing is a security technique used to secure your passwords or texts stored in databases. A hash function is used to generate a string of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1573,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[2,71],"tags":[12],"class_list":["post-1571","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","category-misc","tag-python","entry","has-media"],"_links":{"self":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1571","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/comments?post=1571"}],"version-history":[{"count":1,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1571\/revisions"}],"predecessor-version":[{"id":1572,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1571\/revisions\/1572"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media\/1573"}],"wp:attachment":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media?parent=1571"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/categories?post=1571"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/tags?post=1571"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}