<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ben Falik</title>
    <description>The latest articles on DEV Community by Ben Falik (@takouzlo).</description>
    <link>https://dev.to/takouzlo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3928741%2Fc717ab8c-9e4e-4120-bcfb-84a183f9f4dd.png</url>
      <title>DEV Community: Ben Falik</title>
      <link>https://dev.to/takouzlo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/takouzlo"/>
    <language>en</language>
    <item>
      <title>So, let’s recap. We’ve set up a zero-knowledge authentication server in five minutes. We’ve created an end-to-end encrypted DataVault. And we’ve proven that even in the event of a complete database breach, your data remains mathematically unreadable.</title>
      <dc:creator>Ben Falik</dc:creator>
      <pubDate>Thu, 16 Jul 2026 16:42:48 +0000</pubDate>
      <link>https://dev.to/takouzlo/so-lets-recap-weve-set-up-a-zero-knowledge-authentication-server-in-five-minutes-weve-created-4g06</link>
      <guid>https://dev.to/takouzlo/so-lets-recap-weve-set-up-a-zero-knowledge-authentication-server-in-five-minutes-weve-created-4g06</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a" class="crayons-story__hidden-navigation-link"&gt;🔐 Build a Zero-Knowledge DataVault in 5 Minutes (No Passwords, No Server-Side Secrets)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/takouzlo" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3928741%2Fc717ab8c-9e4e-4120-bcfb-84a183f9f4dd.png" alt="takouzlo profile" class="crayons-avatar__image" width="500" height="300"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/takouzlo" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ben Falik
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ben Falik
                
              
              &lt;div id="story-author-preview-content-4159819" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/takouzlo" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3928741%2Fc717ab8c-9e4e-4120-bcfb-84a183f9f4dd.png" class="crayons-avatar__image" alt="" width="500" height="300"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ben Falik&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 16&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a" id="article-link-4159819"&gt;
          🔐 Build a Zero-Knowledge DataVault in 5 Minutes (No Passwords, No Server-Side Secrets)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cybersecurity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cybersecurity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/zeroknowledge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;zeroknowledge&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              1&lt;span class="hidden s:inline"&gt;&amp;nbsp;comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>database</category>
      <category>privacy</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🔐 Build a Zero-Knowledge DataVault in 5 Minutes (No Passwords, No Server-Side Secrets)</title>
      <dc:creator>Ben Falik</dc:creator>
      <pubDate>Thu, 16 Jul 2026 16:36:29 +0000</pubDate>
      <link>https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a</link>
      <guid>https://dev.to/takouzlo/build-a-zero-knowledge-datavault-in-5-minutes-no-passwords-no-server-side-secrets-m7a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In the age of AI-driven phishing, voice cloning, and automated social engineering, traditional authentication is fundamentally broken. Passwords are leaked, SMS 2FA is intercepted, and even biometrics can be spoofed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  But there is one thing an AI, no matter how powerful, can never steal: a secret that has never touched the internet.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Enter CryptoLogin&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this tutorial, we will build a Zero-Knowledge DataVault from scratch. Your master_secret (e.g., a 32+ character phrase based on family nicknames, kept on a piece of paper in your wallet) will never leave your device. The server will never see it, store it, or even know what it is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's build it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ The Zero-Knowledge Architecture
&lt;/h2&gt;

&lt;p&gt;Unlike traditional systems that send a password (or its hash) to the server&lt;/p&gt;

&lt;p&gt;for verification, CryptoLogin reverses the logic. The server holds no secrets.&lt;/p&gt;

&lt;p&gt;It only issues mathematical challenges that only the holder of the&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;master_secret&lt;/strong&gt; can solve.&lt;/p&gt;

&lt;p&gt;Here is the 3-step authentication flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local Derivation&lt;/strong&gt;: Your device derives a unique &lt;strong&gt;user_id&lt;/strong&gt; from your &lt;strong&gt;master_secret&lt;/strong&gt; using PBKDF2-HMAC-SHA512 (100,000 iterations). The secret never leaves your machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Server Challenge&lt;/strong&gt;: Your device sends the &lt;strong&gt;user_id&lt;/strong&gt; to the server. The server generates a random cryptographic &lt;strong&gt;challenge&lt;/strong&gt; (nonce) and sends it back.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local HMAC Signing&lt;/strong&gt;: Your device signs the &lt;strong&gt;challenge&lt;/strong&gt; locally using HMAC-SHA256 and the derived key. It sends only the signature to the server. The server verifies it in constant time.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Result? If a hacker breaches the server tomorrow, they will only find hex-encoded &lt;strong&gt;user_id&lt;/strong&gt;s and random challenges. Zero passwords. Zero emails. Zero risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Step 1: Spin Up the Auth Server (2 Commands)
&lt;/h2&gt;

&lt;p&gt;The CryptoLogin ecosystem is designed for frictionless developer experience. No complex configurations, no heavy dependencies.&lt;/p&gt;

&lt;p&gt;Open your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install the server package&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;cryptologin[server]

&lt;span class="c"&gt;# 2. Initialize the project (automatically creates `cryptologin_db`)&lt;/span&gt;
cryptologin init

&lt;span class="c"&gt;# 3. Start the server (defaults to http://localhost:8000)&lt;/span&gt;
cryptologin run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ That’s it. Your Zero-Knowledge authentication server is now running and ready to accept challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 Step 2: Basic Zero-Knowledge Authentication (Node.js)
&lt;/h2&gt;

&lt;p&gt;Let’s create a simple client to prove the concept.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;basic-auth &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;basic-auth
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;cryptologin-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an &lt;strong&gt;index.js&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cryptologin-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Your 32+ char master secret. In production, read this from a local file or hardware key.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uncle-jean-1985-marseille-secret-32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8000/api/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Register (Derives user_id locally via PBKDF2)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;demo-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✅ Registered locally.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Login (Solves the server's HMAC challenge locally)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🎉 SUCCESS! Authenticated. Session: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🚪 The server NEVER saw your master_secret.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;❌ Error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it with node index.js. You will see the local derivation and HMAC signing happen in a fraction of a second.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗄️ Step 3: Build the End-to-End Encrypted DataVault
&lt;/h2&gt;

&lt;p&gt;Authentication is great, but what about storing sensitive data? We will now build a DataVault where data is encrypted locally before being sent to the server, using AES-256-GCM (the military-grade standard).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0gap5aio8vx8nha6a8ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0gap5aio8vx8nha6a8ht.png" alt="Screen_app_01" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Vault Server (Python)
&lt;/h3&gt;

&lt;p&gt;Create &lt;strong&gt;vault_server.py&lt;/strong&gt;. Notice the CORS middleware, allowing our local browser demo to communicate with it securely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.middleware.cors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allow_origins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;allow_methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;allow_headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vault.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;check_same_thread&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CREATE TABLE IF NOT EXISTS vault (label TEXT PRIMARY KEY, ciphertext TEXT)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VaultItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/v1/vault/store&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;VaultItem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT OR REPLACE INTO vault (label, ciphertext) VALUES (?, ?)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stored&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/v1/vault/retrieve/{label}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT ciphertext FROM vault WHERE label = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,)).&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ciphertext&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;uvicorn&lt;/span&gt;
    &lt;span class="n"&gt;uvicorn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run it&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;vault_server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzlq95kz4gut9f10lroa4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzlq95kz4gut9f10lroa4.png" alt="Screen_app_02" width="800" height="875"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Local Encryption Client (Node.js)
&lt;/h3&gt;

&lt;p&gt;Create &lt;strong&gt;client.js&lt;/strong&gt; in the same folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cryptologin-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;webcrypto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uncle-jean-1985-marseille-secret-32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8000/api/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VAULT_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8001/api/v1/vault&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 🔐 Derive AES-256 key locally&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keyMaterial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;webcrypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;importKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;raw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PBKDF2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deriveKey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;webcrypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PBKDF2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;enc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cryptologin-datavault-salt-v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SHA-256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;keyMaterial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;encrypt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;decrypt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 🔒 Encrypt locally&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;encryptData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;webcrypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;webcrypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 🔓 Decrypt locally&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;decryptData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plaintext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;webcrypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; 
    &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runVault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🔒 [DataVault] E2E Encryption Test...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 1. Auth (with auto-register fallback)&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;demo-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; 
    &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✅ Authenticated.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Local Encryption&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secretMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My Swiss account number is CH93 0076 2011 6238 5295 745 796 100.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;📝 Original:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secretMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;encryptData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secretMsg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔐 Encrypted payload sent to server:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Store on blind server&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;VAULT_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/store`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bank-account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;💾 Stored on server. The server only sees random noise.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. Retrieve &amp;amp; Local Decryption&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;VAULT_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/retrieve/bank-account`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;decryptData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MASTER_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;🔓 Decrypted locally:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;✨ PROVEN: The server NEVER saw the plaintext.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;runVault&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;strong&gt;"node client.js"&lt;/strong&gt;. Watch the magic happen: the message is encrypted locally, sent as gibberish, and perfectly reconstructed on your machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv058gqfy747onlf03cej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv058gqfy747onlf03cej.png" alt="Screen_app_03" width="800" height="826"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🌐 Try the Visual Demo Yourself
&lt;/h3&gt;

&lt;p&gt;Don't just take my word for it. I built a standalone, dependency-free HTML demo so you can see the Web Crypto API in action right in your browser.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://erabytse.github.io/cryptologin-website/" rel="noopener noreferrer"&gt;👉 Live Demo Page&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Type a secret, encrypt a message, and watch the server blindly store the Base64 ciphertext. Then, decrypt it locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Conclusion: The Secret in Your Wallet
&lt;/h2&gt;

&lt;p&gt;We live in an era where AI can clone voices, generate perfect phishing emails, and automate social engineering at an industrial scale. Passwords, SMS codes, and even biometrics are becoming attack vectors.&lt;/p&gt;

&lt;p&gt;But there is one thing no AI can ever steal: what you keep in your pocket.&lt;/p&gt;

&lt;p&gt;A 32-character &lt;strong&gt;master_secret&lt;/strong&gt; based on family nicknames, an intimate secret phrase, kept on a piece of paper in your wallet. No cloud. No network. No possible leak.&lt;/p&gt;

&lt;p&gt;CryptoLogin doesn't reinvent security. It rehabilitates it. It brings control back to where it should have never left: in your hands.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Not your keys, not your crypto. Not your master_secret, not your account."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🔗 Resources &amp;amp; Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;💻 Full Tutorial Source Code: &lt;a href="https://github.com/erabytse/cryptologin-tutorial" rel="noopener noreferrer"&gt;github.com/erabytse/cryptologin-tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧠 Main CryptoLogin Repo: &lt;a href="//github.com/erabytse/CryptoLogin"&gt;github.com/erabytse/CryptoLogin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐍 PyPI (Server): &lt;a href="//pypi.org/project/cryptologin/"&gt;pypi.org/project/cryptologin/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 npm (Client SDK): &lt;a href="//npmjs.com/package/cryptologin-client"&gt;npmjs.com/package/cryptologin-client&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you found this tutorial valuable, please ⭐ star the GitHub repository and - share it with your dev community. Let's build a safer internet, together.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>cybersecurity</category>
      <category>python</category>
      <category>zeroknowledge</category>
    </item>
    <item>
      <title>In this age of artificial intelligence, is cybersecurity destined to remain the same, or will it no longer be able to protect us?</title>
      <dc:creator>Ben Falik</dc:creator>
      <pubDate>Thu, 02 Jul 2026 09:14:26 +0000</pubDate>
      <link>https://dev.to/takouzlo/in-this-age-of-artificial-intelligence-is-cybersecurity-destined-to-remain-the-same-or-will-it-no-26jc</link>
      <guid>https://dev.to/takouzlo/in-this-age-of-artificial-intelligence-is-cybersecurity-destined-to-remain-the-same-or-will-it-no-26jc</guid>
      <description>&lt;p&gt;That’s an excellent question. In this age of AI, it’s clear that the major cybersecurity firms are powerless against future attacks by AI agents. Anthropic’s Mythos is proof of this. It’s essential to understand that, in theory, only the software’s architect has in-depth knowledge of its vulnerabilities.&lt;br&gt;
That is why I have chosen to use an authentication system where humans remain in control of the keys, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"&lt;strong&gt;CryptoLogin&lt;/strong&gt;"&lt;br&gt;
&lt;a href="https://dev.to/takouzlo/stop-storing-password-hashes-i-built-a-zero-storage-auth-system-for-the-ai-era-3djg"&gt;https://dev.to/takouzlo/stop-storing-password-hashes-i-built-a-zero-storage-auth-system-for-the-ai-era-3djg&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With this system, the master_secret remains under the user’s control, unless they choose to store it in a cloud accessible to AI. I am convinced that a traditional notebook is the key to success.&lt;/p&gt;

&lt;p&gt;I keep my precious passcode, my master_secret, safely tucked away on a small piece of paper in my wallet, far from the prying eyes of the cloud. In this way, I am confident that I can fend off future attacks from our virtual colleagues(AIA). It is regrettable to note that ‘MYTHOS’ has already established this as a fact. 💪🤞🫡😎&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ai</category>
      <category>cybersecurity</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Stop Storing Password Hashes: I Built a "Zero-Storage" Auth System for the AI Era</title>
      <dc:creator>Ben Falik</dc:creator>
      <pubDate>Tue, 30 Jun 2026 13:14:08 +0000</pubDate>
      <link>https://dev.to/takouzlo/stop-storing-password-hashes-i-built-a-zero-storage-auth-system-for-the-ai-era-3djg</link>
      <guid>https://dev.to/takouzlo/stop-storing-password-hashes-i-built-a-zero-storage-auth-system-for-the-ai-era-3djg</guid>
      <description>&lt;h2&gt;
  
  
  A passwordless authentication system where the server knows absolutely nothing about your users. Zero honeypots, zero breaches, zero regrets.
&lt;/h2&gt;




&lt;blockquote&gt;
&lt;p&gt;I built an authentication system where the server stores &lt;strong&gt;zero secrets&lt;/strong&gt;. No password hashes, no emails, no recovery tokens. The server only knows a &lt;code&gt;user_id&lt;/code&gt; derived from the user's &lt;code&gt;master_secret&lt;/code&gt;, and authentication is proven cryptographically via HMAC. If the database is breached, there's literally nothing to steal.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔥 The Problem: Your Auth Database is a Ticking Time Bomb
&lt;/h2&gt;

&lt;p&gt;Let's be brutally honest about modern authentication:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every authentication system is a honeypot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even with Argon2id, bcrypt, or scrypt, you're still storing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password hashes (crackable with enough GPU power)&lt;/li&gt;
&lt;li&gt;Email addresses (for credential stuffing attacks)&lt;/li&gt;
&lt;li&gt;Password reset tokens (if stolen, game over)&lt;/li&gt;
&lt;li&gt;Session tokens (if leaked, instant access)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The AI Multiplier
&lt;/h3&gt;

&lt;p&gt;In 2026, AI has made this &lt;strong&gt;10x worse&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pattern Recognition:&lt;/strong&gt; AI can cross-reference leaked databases in seconds, finding correlations humans would miss&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Dictionary Attacks:&lt;/strong&gt; AI generates context-aware password guesses based on user profiles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Credential Stuffing:&lt;/strong&gt; AI tests millions of leaked credentials across platforms simultaneously&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Engineering:&lt;/strong&gt; AI crafts personalized phishing attacks using leaked data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The uncomfortable truth:&lt;/strong&gt; If a hacker gets your database, it's not a matter of &lt;em&gt;if&lt;/em&gt; they'll exploit it, but &lt;em&gt;how fast&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Question
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What if we could build an auth system where &lt;strong&gt;there's nothing to steal&lt;/strong&gt;?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  💡 The Solution: CryptoLogin - Zero-Storage Authentication
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The time is now ripe for it&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Ferabytse%2FCryptoLogin%2Fmain%2Fimages%2FCryptoLogin.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Ferabytse%2FCryptoLogin%2Fmain%2Fimages%2FCryptoLogin.gif" width="800" height="400" alt="CryptoLogin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CryptoLogin uses a challenge-response mechanism inspired by Zero-Knowledge principles.&lt;br&gt;
The server never stores your secret. Your secret never leaves your device.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I built &lt;strong&gt;CryptoLogin&lt;/strong&gt;, an authentication system based on a radical principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The server should never know anything about the user that the user doesn't explicitly share.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Core Principles
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No secrets on the server&lt;/strong&gt; - No password hashes, no emails, no recovery tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client-side derivation&lt;/strong&gt; - The &lt;code&gt;user_id&lt;/code&gt; is derived locally from the &lt;code&gt;master_secret&lt;/code&gt; using PBKDF2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HMAC-based authentication&lt;/strong&gt; - The client proves knowledge of the &lt;code&gt;master_secret&lt;/code&gt; via cryptographic signature&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-knowledge flow&lt;/strong&gt; - The &lt;code&gt;master_secret&lt;/code&gt; never leaves the browser&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What the Server Actually Stores
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- That's it. Just a user_id and some metadata.&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;-- 64-char hex, derived from master_secret&lt;/span&gt;
    &lt;span class="n"&gt;user_data&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                  &lt;span class="c1"&gt;-- Optional JSON metadata&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_activity_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;challenge&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;                   &lt;span class="c1"&gt;-- Temporary, for active login sessions only&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No passwords. No emails. No secrets.&lt;/strong&gt; If this database is breached, the attacker gets... a bunch of random-looking hex strings. Useless.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 How It Works: The Zero-Knowledge Flow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Cryptographic Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────┐                              ┌──────────┐
│  Client  │                              │  Server  │
└────┬─────┘                              └────┬─────┘
     │ 1. Derive user_id from master_secret    │
     │    (PBKDF2-SHA512, 100k iterations)     │
     │                                         │
     │ 2. POST /auth/login/init {user_id}      │
     │ ──────────────────────────────────────► │
     │                                         │ 3. Generate challenge
     │    4. Return challenge                  │
     │ ◄────────────────────────────────────── │
     │                                         │
     │ 5. Compute HMAC(challenge, user_id)     │
     │                                         │
     │ 6. POST /auth/login/verify              │
     │    {user_id, hmac}                      │
     │ ──────────────────────────────────────► │
     │                                         │ 7. Verify HMAC
     │    8. Return session                    │
     │ ◄────────────────────────────────────── │
     │                                         │
     ✅ Authenticated                          ✅ Session created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This is Secure
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;master_secret&lt;/code&gt; never leaves the browser&lt;/strong&gt; - It's only used locally to derive &lt;code&gt;user_id&lt;/code&gt; and compute HMAC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The server can't impersonate the user&lt;/strong&gt; - It doesn't know the &lt;code&gt;master_secret&lt;/code&gt;, only the derived &lt;code&gt;user_id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replay attacks are impossible&lt;/strong&gt; - Each challenge is single-use and expires after login&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database breaches are harmless&lt;/strong&gt; - The attacker gets &lt;code&gt;user_id&lt;/code&gt; values, which are useless without the &lt;code&gt;master_secret&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Cryptographic Standards
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key Derivation&lt;/td&gt;
&lt;td&gt;PBKDF2-SHA512 (100,000 iterations)&lt;/td&gt;
&lt;td&gt;Derive &lt;code&gt;user_id&lt;/code&gt; from &lt;code&gt;master_secret&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;HMAC-SHA256&lt;/td&gt;
&lt;td&gt;Prove knowledge of &lt;code&gt;master_secret&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparison&lt;/td&gt;
&lt;td&gt;Constant-time comparison&lt;/td&gt;
&lt;td&gt;Prevent timing attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;No custom crypto.&lt;/strong&gt; Everything uses industry-standard algorithms via the Web Crypto API (browser) and Python's &lt;code&gt;hashlib&lt;/code&gt;/&lt;code&gt;hmac&lt;/code&gt; (server).&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Integration in 5 Minutes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Backend (Python/Flask)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;cryptologin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptologin&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CryptoLogin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptologin.core.user_manager_v2&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserManagerV2&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptologin.storage.sqlite_v2&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SQLiteStorageV2&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize CryptoLogin
&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SQLiteStorageV2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auth.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auto_migrate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;user_manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UserManagerV2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/auth/register_v2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Derived client-side from master_secret
&lt;/span&gt;    &lt;span class="n"&gt;user_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register_user_v2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/auth/login/init_v2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;login_init&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;challenge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initiate_login_v2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Returns plaintext challenge
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;challenge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/auth/login/verify_v2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;login_verify&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;hmac_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;challenge_response&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# HMAC from client
&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete_login_v2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hmac_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;session_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expires_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expires_at&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend (JavaScript)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;cryptologin-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cryptologin-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize the client&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.yourapp.com/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Registration (user provides master_secret)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;masterSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// SDK derives user_id automatically&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;masterSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;  &lt;span class="c1"&gt;// Optional metadata&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Registered:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Login (user provides master_secret)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;masterSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// SDK handles everything:&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Derives user_id&lt;/span&gt;
  &lt;span class="c1"&gt;// 2. Gets challenge from server&lt;/span&gt;
  &lt;span class="c1"&gt;// 3. Computes HMAC locally&lt;/span&gt;
  &lt;span class="c1"&gt;// 4. Sends HMAC to server&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;masterSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Logged in:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;masterSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-super-secret-passphrase-min-32-chars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;masterSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;masterSecret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;That's it.&lt;/strong&gt; The SDK handles all the cryptography. You just pass the &lt;code&gt;master_secret&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ The Brutal Truth: Trade-offs
&lt;/h2&gt;

&lt;p&gt;I'm not going to sell you a fantasy. CryptoLogin is &lt;strong&gt;not for everyone&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What You Lose
&lt;/h3&gt;

&lt;p&gt;❌ &lt;strong&gt;No "Forgot Password" flow&lt;/strong&gt; - If the user loses their &lt;code&gt;master_secret&lt;/code&gt;, they're locked out &lt;strong&gt;forever&lt;/strong&gt;. The server can't help because it doesn't know the secret.&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;No email-based recovery&lt;/strong&gt; - Since we don't store emails, there's no way to send recovery links.&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;User responsibility&lt;/strong&gt; - Users must store their &lt;code&gt;master_secret&lt;/code&gt; securely (password manager, hardware key, etc.)&lt;/p&gt;

&lt;h3&gt;
  
  
  What You Gain
&lt;/h3&gt;

&lt;p&gt;✅ &lt;strong&gt;Zero breach risk&lt;/strong&gt; - If your database is leaked, there's nothing to exploit&lt;br&gt;
✅ &lt;strong&gt;No password hashing costs&lt;/strong&gt; - No CPU-intensive bcrypt/Argon2 on every login&lt;br&gt;
✅ &lt;strong&gt;Simplified compliance&lt;/strong&gt; - No password storage = no PCI-DSS/GDPR headaches for credentials&lt;br&gt;
✅ &lt;strong&gt;True user sovereignty&lt;/strong&gt; - Users own their authentication completely&lt;/p&gt;

&lt;h3&gt;
  
  
  Who Should Use CryptoLogin?
&lt;/h3&gt;

&lt;p&gt;✅ &lt;strong&gt;High-security applications&lt;/strong&gt; - Financial apps, healthcare, enterprise tools&lt;br&gt;
✅ &lt;strong&gt;Privacy-focused products&lt;/strong&gt; - Where users demand zero-knowledge architecture&lt;br&gt;
✅ &lt;strong&gt;Developer tools&lt;/strong&gt; - Where users are technical enough to manage a &lt;code&gt;master_secret&lt;/code&gt;&lt;br&gt;
✅ &lt;strong&gt;Decentralized apps&lt;/strong&gt; - Where server-side secrets are an anti-pattern&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Consumer apps with non-technical users&lt;/strong&gt; - If your users will forget their password, this isn't for you&lt;br&gt;
❌ &lt;strong&gt;Apps requiring email recovery&lt;/strong&gt; - If you need "Forgot Password", stick with traditional auth&lt;/p&gt;

&lt;h3&gt;
  
  
  The Bitcoin Analogy
&lt;/h3&gt;

&lt;p&gt;CryptoLogin works like a Bitcoin wallet:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Not your keys, not your crypto."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Not your master_secret, not your account."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's the ultimate trade-off: &lt;strong&gt;Absolute security vs. Convenience&lt;/strong&gt;. You choose.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Performance &amp;amp; Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test Coverage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;✓ tests/crypto.test.js (18 tests)
  ✓ deriveUserId (5 tests)
  ✓ computeHmac (5 tests)
  ✓ isValidUserId (4 tests)
  ✓ generateChallenge (4 tests)

✓ tests/client.test.js (8 tests)
  ✓ constructor (4 tests)
  ✓ session management (4 tests)

Test Files  2 passed (2)
     Tests  26 passed (26)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Performance Benchmarks
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deriveUserId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~150ms&lt;/td&gt;
&lt;td&gt;PBKDF2 with 100k iterations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;computeHmac&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~1ms&lt;/td&gt;
&lt;td&gt;HMAC-SHA256 is fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full login flow&lt;/td&gt;
&lt;td&gt;~200ms&lt;/td&gt;
&lt;td&gt;Network + crypto&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The 150ms for &lt;code&gt;deriveUserId&lt;/code&gt; is intentional. It's a security feature, not a bug. Slow key derivation makes brute-force attacks expensive.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Real-World Demo
&lt;/h2&gt;

&lt;p&gt;I've deployed a live demo where you can test CryptoLogin right now:&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://erabytse.github.io/cryptologin-website/demo_v2.html" rel="noopener noreferrer"&gt;https://erabytse.github.io/cryptologin-website/demo_v2.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter a &lt;code&gt;master_secret&lt;/code&gt; (minimum 32 characters)&lt;/li&gt;
&lt;li&gt;Click "Register"&lt;/li&gt;
&lt;li&gt;Click "Login"&lt;/li&gt;
&lt;li&gt;Watch the HMAC-based authentication in action&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The demo connects to a real API endpoint: &lt;code&gt;https://api.docudeeper.com/api/v1&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Links &amp;amp; Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Packages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python SDK (Server):&lt;/strong&gt; &lt;a href="https://pypi.org/project/cryptologin/" rel="noopener noreferrer"&gt;cryptologin on PyPI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript SDK (Client):&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/cryptologin-client" rel="noopener noreferrer"&gt;cryptologin-client on npm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend (Python):&lt;/strong&gt; &lt;a href="https://github.com/erabytse/CryptoLogin" rel="noopener noreferrer"&gt;github.com/erabytse/CryptoLogin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend (JavaScript):&lt;/strong&gt; &lt;a href="https://github.com/erabytse/cryptologin-client" rel="noopener noreferrer"&gt;github.com/erabytse/cryptologin-client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo Website:&lt;/strong&gt; &lt;a href="https://github.com/erabytse/cryptologin-website" rel="noopener noreferrer"&gt;github.com/erabytse/cryptologin-website&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://erabytse.github.io/cryptologin-website/" rel="noopener noreferrer"&gt;https://erabytse.github.io/cryptologin-website/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Docs:&lt;/strong&gt; See README on GitHub repos&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤝 Contributing
&lt;/h2&gt;

&lt;p&gt;CryptoLogin is open-source under the MIT License. Contributions are welcome!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Areas where we need help:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧪 More test coverage&lt;/li&gt;
&lt;li&gt;📚 Documentation improvements&lt;/li&gt;
&lt;li&gt;🔌 SDKs for other languages (Rust, Go, PHP)&lt;/li&gt;
&lt;li&gt;🎨 UI/UX improvements for the demo&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💬 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Authentication doesn't have to be a compromise between security and usability. With CryptoLogin, we've proven that you can build a system where:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The server knows nothing&lt;/strong&gt; about the user's secret&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication is cryptographically proven&lt;/strong&gt; via HMAC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database breaches are harmless&lt;/strong&gt; because there's nothing to steal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration is trivial&lt;/strong&gt; thanks to well-designed SDKs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Is it for everyone? No. But for the right use case, it's a game-changer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The future of auth isn't about building better honeypots. It's about removing the honey.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this useful, give the repos a ⭐ on GitHub and share it with your network. Let's build a more secure web, one zero-knowledge system at a time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions? Drop them in the comments. I read everything.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Built with ❤️ by erabytse&lt;/p&gt;

&lt;p&gt;Reinventing Authentication. One Secret at a Time.&lt;/p&gt;

&lt;p&gt;A quiet rebellion against digital waste.&lt;/p&gt;

</description>
      <category>security</category>
      <category>authentication</category>
      <category>cryptography</category>
      <category>privacy</category>
    </item>
    <item>
      <title>DocuDeeper: The Offline-First AI Assistant for Sensitive Document Analysis (Developers, Meet Your New Privacy Power Tool)</title>
      <dc:creator>Ben Falik</dc:creator>
      <pubDate>Fri, 22 May 2026 11:25:13 +0000</pubDate>
      <link>https://dev.to/takouzlo/docudeeper-the-offline-first-ai-assistant-for-sensitive-document-analysis-developers-meet-your-4j1d</link>
      <guid>https://dev.to/takouzlo/docudeeper-the-offline-first-ai-assistant-for-sensitive-document-analysis-developers-meet-your-4j1d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Analyze confidential documents with AI — without sending a single byte to the cloud.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're a developer, security engineer, or tech lead working with sensitive data (legal docs, financial reports, internal audits, healthcare records), you know the dilemma: AI is powerful, but privacy is non-negotiable.&lt;br&gt;
Enter DocuDeeper — a locally-run, GDPR-compliant document analysis assistant built for professionals who refuse to compromise on confidentiality.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔐 Why DocuDeeper Exists (And Why You Should Care)
&lt;/h2&gt;

&lt;p&gt;Most AI document tools require uploading files to external servers. That's a hard no for:&lt;br&gt;
    • Legal teams handling NDAs or litigation files&lt;br&gt;
    • Finance departments processing quarterly reports&lt;br&gt;
    • Healthcare or HR professionals managing PII&lt;br&gt;
    • Developers building compliance-first applications&lt;br&gt;
DocuDeeper flips the script:&lt;br&gt;
✅ 100% offline — Your documents never leave your machine&lt;br&gt;
✅ Zero cloud dependency — No APIs, no webhooks, no data exfiltration risk&lt;br&gt;
✅ GDPR-by-design — Built for EU professionals, auditors, and regulated industries&lt;br&gt;
✅ Local LLMs — Intelligence runs on your hardware, not a third-party server&lt;br&gt;
This isn't just a "privacy feature." It's the core architecture.&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ What Developers Get: Features That Matter
&lt;/h2&gt;

&lt;p&gt;🔍 Contextual, Fact-Based Q&amp;amp;A&lt;/p&gt;

&lt;p&gt;Ask precise questions about your document. DocuDeeper returns answers strictly grounded in your content — no hallucinations, no creative improvisation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Example prompt:
"Summarize the liability clauses in section 4.2 of this contract."

// Output:
"Section 4.2 limits vendor liability to the total amount paid under the agreement, 
excluding cases of gross negligence or willful misconduct."

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌐 Multilingual by Default
&lt;/h2&gt;

&lt;p&gt;Automatic detection and analysis in French, English, and German. No configuration needed. Perfect for cross-border teams or multilingual documentation.&lt;/p&gt;

&lt;p&gt;📁 Format Flexibility&lt;br&gt;
Premium supports: PDF, TXT, Excel (.xlsx/.xls), Word (.docx)&lt;br&gt;
→ Parse, query, and export without format friction.&lt;br&gt;
📤 Professional PDF Export&lt;br&gt;
Generate audit-ready reports with citations and structured answers. Ideal for client deliverables or internal documentation.&lt;br&gt;
⚡ Lightweight &amp;amp; Efficient&lt;br&gt;
Optimized to run on modest hardware. No GPU required. Perfect for laptops, secure workstations, or air-gapped environments.&lt;/p&gt;

&lt;p&gt;💡 Real-World Use Cases for Dev Teams&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;How DocuDeeper Helps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compliance Audits&lt;/td&gt;
&lt;td&gt;Analyze policy documents offline; export findings without exposing sensitive content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legal Tech Prototypes&lt;/td&gt;
&lt;td&gt;Test document-QA workflows locally before integrating with secure backends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal Knowledge Bases&lt;/td&gt;
&lt;td&gt;Query internal PDFs/Word docs without indexing them in cloud vector DBs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Due Diligence Automation&lt;/td&gt;
&lt;td&gt;Rapidly extract clauses, obligations, or risks from M&amp;amp;A documents — 100% on-prem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privacy-First AI Research&lt;/td&gt;
&lt;td&gt;Experiment with local LLMs on real documents without data governance overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🧭 How It Works (Simple Integration Mindset)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Load your document (drag &amp;amp; drop or CLI in future versions)&lt;/li&gt;
&lt;li&gt;Ask natural language questions&lt;/li&gt;
&lt;li&gt;Get factual, cited answers — export or iterate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No API keys. No environment variables. No network permissions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Just: install → load → query → done.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;🔧 Pro tip for devs: Use the Free online version to prototype your workflow, then switch to Premium for production-grade, offline deployment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🌍 Built for the Real World (Not Just the Cloud)
&lt;/h2&gt;

&lt;p&gt;DocuDeeper isn't trying to replace your cloud AI stack. It solves a specific, critical gap:&lt;br&gt;
"How do I leverage LLM intelligence when my data legally cannot leave this machine?"&lt;/p&gt;

&lt;p&gt;That's why it's trusted by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Legal consultants in Paris&lt;/li&gt;
&lt;li&gt;Auditors in Berlin&lt;/li&gt;
&lt;li&gt;Strategy firms in Geneva&lt;/li&gt;
&lt;li&gt;And increasingly, dev teams building privacy-aware tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Final Thought: Privacy Isn't a Feature — It's a Foundation
&lt;/h2&gt;

&lt;p&gt;In an era of data breaches, regulatory scrutiny, and AI ethics debates, choosing where your data flows is a technical decision with legal consequences.&lt;br&gt;
DocuDeeper gives developers and professionals a pragmatic, powerful option:&lt;br&gt;
🔹 Harness modern AI&lt;br&gt;
🔹 Keep full control of your data&lt;br&gt;
🔹 Stay compliant by design&lt;br&gt;
No subscriptions. No hidden telemetry. No compromises.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✨ Ready to try?&lt;br&gt;
→ Test the Free online version (TXT, 5k chars/day)&lt;br&gt;
Built in Europe. Engineered for trust.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Disclaimer: This article is not sponsored. I'm sharing DocuDeeper because privacy-first tooling deserves more visibility in the dev community. Always evaluate tools against your organization's security and compliance requirements.&lt;br&gt;
🔗 Resources&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;a href="https://docudeeper.com/" rel="noopener noreferrer"&gt;DocuDeeper Official Site&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📄 GDPR Compliance Overview&lt;/li&gt;
&lt;li&gt;💬 Questions? Drop them below — let's discuss offline AI, local LLMs, and privacy engineering! 👇&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you found this useful, follow me for more deep dives on developer tools, privacy tech, and pragmatic AI workflows. 🙌&lt;/p&gt;

</description>
      <category>legaltech</category>
      <category>privacyfirst</category>
      <category>offlineai</category>
      <category>documentanalysis</category>
    </item>
    <item>
      <title>⚡ Flash512-Vanguard: Military-Grade Encryption for Python (AES-256-GCM + Argon2id + SecureBuffer)</title>
      <dc:creator>Ben Falik</dc:creator>
      <pubDate>Wed, 13 May 2026 11:07:38 +0000</pubDate>
      <link>https://dev.to/takouzlo/flash512-vanguard-military-grade-encryption-for-python-aes-256-gcm-argon2id-securebuffer-8bc</link>
      <guid>https://dev.to/takouzlo/flash512-vanguard-military-grade-encryption-for-python-aes-256-gcm-argon2id-securebuffer-8bc</guid>
      <description>&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/erabytse/flash512-vanguard/main/assets/flash512_banner.png" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/erabytse/flash512-vanguard/main/assets/flash512_banner.png&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Problem We All Share&lt;br&gt;
You need encryption. But implementing AES-GCM correctly? Managing nonces? Deriving keys properly? Wiping sensitive data from memory?&lt;/p&gt;

&lt;p&gt;One mistake = total compromise.&lt;/p&gt;

&lt;p&gt;I built Flash512-Vanguard so you never have to worry about any of this.&lt;/p&gt;

&lt;p&gt;🛡️ What Is It?&lt;br&gt;
A secure-by-default encryption library for Python that combines:&lt;/p&gt;

&lt;p&gt;Layer   Implementation  Standard&lt;br&gt;
Primary KDF Argon2id (memory-hard)  OWASP ASVS v2.4&lt;br&gt;
Fallback KDF    PBKDF2-HMAC-SHA512 (100k iterations)    OWASP&lt;br&gt;
Encryption  AES-256-GCM (128-bit tag)   NIST FIPS 197&lt;br&gt;
Nonce   Cryptographically random per operation  NIST SP 800-38D&lt;br&gt;
Memory  SecureBuffer with automatic wiping  Military-grade&lt;br&gt;
Integrity   Module tamper-checking at load  Anti-tampering&lt;br&gt;
🚀 Three Lines of Code. That's It.&lt;br&gt;
python&lt;br&gt;
from flash512 import Flash512Vanguard&lt;/p&gt;

&lt;h2&gt;
  
  
  Encrypt
&lt;/h2&gt;

&lt;p&gt;token = Flash512Vanguard.protect("Your Secret Data", "user-password")&lt;/p&gt;

&lt;h2&gt;
  
  
  Decrypt
&lt;/h2&gt;

&lt;p&gt;original = Flash512Vanguard.open(token, "user-password")&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify without decrypting
&lt;/h2&gt;

&lt;p&gt;is_valid = Flash512Vanguard.verify(token, "user-password")&lt;br&gt;
🔐 Military-Grade Features (v2.1+)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automatic Memory Wiping
python
with Flash512Vanguard.open(token, password) as buffer:
process_sensitive_data(buffer.data)
## Data ZEROED from RAM. Gone. Forever.&lt;/li&gt;
&lt;li&gt;Key Rotation (Password Changes)
python
new_token = Flash512Vanguard.rotate_secret(
old_token, "old_password", "new_password"
)
## Your data stays the same. Only the key changes.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Polymorphic Output&lt;br&gt;
Same message → different token every time (random nonce). No pattern leakage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anti-Brute Force&lt;br&gt;
Argon2id makes GPU/ASIC attacks economically impossible.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💻 Quick Install&lt;br&gt;
bash&lt;br&gt;
pip install flash512-vanguard==2.1.1&lt;br&gt;
🔑 One-Time Configuration&lt;br&gt;
bash&lt;br&gt;
export FLASH512_VANGUARD_CORE="your-64-char-min-random-secret"&lt;br&gt;
Add to .env (never commit to git):&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
FLASH512_VANGUARD_CORE=your-secure-random-secret-64-chars-min&lt;br&gt;
📊 Who Is This For?&lt;br&gt;
Use Case    Works?&lt;br&gt;
Protecting PII in databases ✅ Yes&lt;br&gt;
Encrypting API keys at rest ✅ Yes&lt;br&gt;
Secure user data for SaaS   ✅ Yes&lt;br&gt;
Compliance (SOC2, HIPAA)    ✅ Yes&lt;br&gt;
HSM/TPM integration ✅ Enterprise tier&lt;br&gt;
🧪 Test Before Trusting&lt;br&gt;
bash&lt;br&gt;
pip install -e .[dev]&lt;br&gt;
pytest tests/ -v  # 500+ test cases&lt;br&gt;
pytest tests/test_military_grade.py -v&lt;br&gt;
📦 Where to Get It&lt;br&gt;
PyPI: flash512-vanguard&lt;/p&gt;

&lt;p&gt;GitHub: erabytse/flash512-vanguard&lt;/p&gt;

&lt;p&gt;License: Apache 2.0 (free for commercial use)&lt;/p&gt;

&lt;p&gt;💼 Commercial Support&lt;br&gt;
Need SLA, HSM integration, or security audit?&lt;/p&gt;

&lt;p&gt;Tier    Price   Includes&lt;br&gt;
Core    Free    Full encryption engine&lt;br&gt;
Pro Support €499/month    24h SLA, priority patches&lt;br&gt;
Enterprise  Custom  HSM/TPM, SIEM, training&lt;br&gt;
📧 Contact: &lt;a href="mailto:contact@fbfconsulting.org"&gt;contact@fbfconsulting.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙏 Why I Built This&lt;br&gt;
In an era of cyber threats, encryption should be more than a standard. It should be an evolving fortress.&lt;/p&gt;

&lt;p&gt;Flash512-Vanguard is my contribution to Digital Sovereignty and Advanced Privacy. Security through transparency, not obscurity. Peer-reviewed standards so you can sleep at night.&lt;/p&gt;

&lt;p&gt;🔮 What's Next?&lt;br&gt;
Hardware security key support&lt;/p&gt;

&lt;p&gt;Post-quantum cryptography preparation&lt;/p&gt;

&lt;p&gt;FIPS 140-3 validation (planned 2027)&lt;/p&gt;

&lt;p&gt;📞 Support&lt;br&gt;
Need    Contact&lt;br&gt;
Bug report  &lt;a href="mailto:contact@fbfconsulting.org"&gt;contact@fbfconsulting.org&lt;/a&gt; (private)&lt;br&gt;
Technical help  &lt;a href="mailto:support@fbfconsulting.org"&gt;support@fbfconsulting.org&lt;/a&gt;&lt;br&gt;
Commercial  &lt;a href="mailto:contact@fbfconsulting.org"&gt;contact@fbfconsulting.org&lt;/a&gt;&lt;br&gt;
⚡ Start protecting your data today.&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
pip install flash512-vanguard==2.1.1&lt;br&gt;
"Engineered for extreme privacy, designed for the international cybersecurity community."&lt;/p&gt;

&lt;p&gt;P.S. This library follows the PoetryCoding™ philosophy: code as an act of care. Protect without locking away. Remember without exposing.&lt;/p&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>cryptography</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
