<?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>Forem: Patryk Sowiński</title>
    <description>The latest articles on Forem by Patryk Sowiński (@treszyk).</description>
    <link>https://forem.com/treszyk</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3840532%2F50a74c63-6297-4a4e-82f8-ef51f5403155.png</url>
      <title>Forem: Patryk Sowiński</title>
      <link>https://forem.com/treszyk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/treszyk"/>
    <language>en</language>
    <item>
      <title>Architecture vs Brute-Force: What I Learned Benchmarking KDFs for my Thesis</title>
      <dc:creator>Patryk Sowiński</dc:creator>
      <pubDate>Wed, 22 Apr 2026 09:54:58 +0000</pubDate>
      <link>https://forem.com/treszyk/architecture-vs-brute-force-what-i-learned-benchmarking-kdfs-for-my-thesis-18bo</link>
      <guid>https://forem.com/treszyk/architecture-vs-brute-force-what-i-learned-benchmarking-kdfs-for-my-thesis-18bo</guid>
      <description>&lt;p&gt;Choosing a KDF is a trade-off between user verification time and the brute-force cost for an attacker. For my bachelor’s thesis project, &lt;a href="https://github.com/treszyk/vaulton-password-manager" rel="noopener noreferrer"&gt;Vaulton&lt;/a&gt;, I wanted to look past theoretical recommendations and get empirical data on how these algorithms perform across different hardware tiers.&lt;/p&gt;

&lt;p&gt;I benchmarked Argon2id, Bcrypt, and PBKDF2 across a range of devices from an &lt;strong&gt;Intel iGPU&lt;/strong&gt; to an &lt;strong&gt;RTX 5080&lt;/strong&gt; to identify their real-world breaking points. This post covers the data from those tests, the hardware bottlenecks I identified, and how different architectures respond to memory-hard functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hardness of the Problem
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;PBKDF2-SHA256&lt;/strong&gt;: A NIST-standard algorithm that is primarily CPU-bound. Its largest weakness in modern security is its low memory requirement, which makes it highly parallelizable on GPUs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Bcrypt&lt;/strong&gt;: Based on the Blowfish cipher, it introduces some memory requirements (a 4KB S-box) that complicate GPU implementation. While it remains competitive in terms of throughput, it is naturally limited by its age and fixed memory usage.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Argon2id&lt;/strong&gt;: The winner of the Password Hashing Competition (2015). It is designed specifically to be &lt;strong&gt;Memory-Hard&lt;/strong&gt;, forcing attackers to dedicate physical RAM per thread, which significantly limits the parallelization capabilities of GPUs and ASICs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Test Environment
&lt;/h2&gt;

&lt;p&gt;Benchmarks were performed across three distinct hardware configurations representing various levels of compute power and memory architectures.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;GPU&lt;/th&gt;
&lt;th&gt;Memory Architecture&lt;/th&gt;
&lt;th&gt;CPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Intel® Arc™ Graphics (iGPU)&lt;/td&gt;
&lt;td&gt;8018 MB (Shared)&lt;/td&gt;
&lt;td&gt;Intel® Core™ Ultra 7 265K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NVIDIA GTX 1660 Ti&lt;/td&gt;
&lt;td&gt;6143 MB (VRAM)&lt;/td&gt;
&lt;td&gt;Intel® Core™ i5-9300HF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NVIDIA GeForce RTX 5080&lt;/td&gt;
&lt;td&gt;16302 MB (VRAM)&lt;/td&gt;
&lt;td&gt;Intel® Core™ Ultra 7 265K&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: Attacker throughput was measured using &lt;strong&gt;Hashcat 7.1.2&lt;/strong&gt; (offline attack model, single device).&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology: Normalizing for User Cost
&lt;/h2&gt;

&lt;p&gt;When choosing parameters for a password manager, the goal is to maximize security while maintaining a consistent user experience. I normalized the parameters so that the verification time falls into three distinct "UX profiles" (Low, Medium, and High) based on performance on a mid-range laptop (System 2).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Profile&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Hashcat mode&lt;/th&gt;
&lt;th&gt;Parameters&lt;/th&gt;
&lt;th&gt;Verification Time (System 2)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PBKDF2&lt;/td&gt;
&lt;td&gt;10900&lt;/td&gt;
&lt;td&gt;250,000 iterations&lt;/td&gt;
&lt;td&gt;0.157s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Bcrypt&lt;/td&gt;
&lt;td&gt;3200&lt;/td&gt;
&lt;td&gt;Cost Factor 11&lt;/td&gt;
&lt;td&gt;0.186s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;34000&lt;/td&gt;
&lt;td&gt;64 MB RAM&lt;/td&gt;
&lt;td&gt;0.178s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Medium&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PBKDF2&lt;/td&gt;
&lt;td&gt;10900&lt;/td&gt;
&lt;td&gt;500,000 iterations&lt;/td&gt;
&lt;td&gt;0.315s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Bcrypt&lt;/td&gt;
&lt;td&gt;3200&lt;/td&gt;
&lt;td&gt;Cost Factor 12&lt;/td&gt;
&lt;td&gt;0.371s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;34000&lt;/td&gt;
&lt;td&gt;128 MB RAM&lt;/td&gt;
&lt;td&gt;0.370s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PBKDF2&lt;/td&gt;
&lt;td&gt;10900&lt;/td&gt;
&lt;td&gt;1,000,000 iterations&lt;/td&gt;
&lt;td&gt;0.628s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Bcrypt&lt;/td&gt;
&lt;td&gt;3200&lt;/td&gt;
&lt;td&gt;Cost Factor 13&lt;/td&gt;
&lt;td&gt;0.743s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;34000&lt;/td&gt;
&lt;td&gt;256 MB RAM&lt;/td&gt;
&lt;td&gt;0.741s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: All Argon2id tests used 3 iterations and a parallelism factor of 1.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark Results (Throughput in H/s)
&lt;/h2&gt;

&lt;p&gt;The following table presents the raw throughput (Hashes per second) for each algorithm at the normalized security levels across all systems.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hardware&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Low&lt;/th&gt;
&lt;th&gt;Medium&lt;/th&gt;
&lt;th&gt;High&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System 1 (iGPU)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PBKDF2-SHA256&lt;/td&gt;
&lt;td&gt;1726&lt;/td&gt;
&lt;td&gt;755&lt;/td&gt;
&lt;td&gt;382&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Bcrypt&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System 2 (1660 Ti)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PBKDF2-SHA256&lt;/td&gt;
&lt;td&gt;3998&lt;/td&gt;
&lt;td&gt;2054&lt;/td&gt;
&lt;td&gt;996&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Bcrypt&lt;/td&gt;
&lt;td&gt;346&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;360&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System 3 (RTX 5080)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PBKDF2-SHA256&lt;/td&gt;
&lt;td&gt;25236&lt;/td&gt;
&lt;td&gt;12612&lt;/td&gt;
&lt;td&gt;6271&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Bcrypt&lt;/td&gt;
&lt;td&gt;2390&lt;/td&gt;
&lt;td&gt;1195&lt;/td&gt;
&lt;td&gt;598&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;1164&lt;/td&gt;
&lt;td&gt;332&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Baseline Comparison (SHA-256)
&lt;/h3&gt;

&lt;p&gt;For context, the raw SHA-256 throughput (Baseline, Hashcat mode 1400) on these systems was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;iGPU&lt;/strong&gt;: 1084 MH/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GTX 1660 Ti&lt;/strong&gt;: 2329 MH/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RTX 5080&lt;/strong&gt;: 15263 MH/s&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Analysis: The Attacker's Bottleneck
&lt;/h2&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.amazonaws.com%2Fuploads%2Farticles%2Fkpu92oa0amz3s9pt501e.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.amazonaws.com%2Fuploads%2Farticles%2Fkpu92oa0amz3s9pt501e.png" alt="Security Horizon" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 1: Comparison of security horizon across different password hashing algorithms.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Resiliency of Bcrypt
&lt;/h3&gt;

&lt;p&gt;In terms of raw H/s throughput, Bcrypt remains relatively efficient for attackers compared to memory-hard algorithms. On the RTX 5080, it maintains roughly &lt;strong&gt;6.8x&lt;/strong&gt; higher throughput than Argon2id at high security levels (&lt;strong&gt;598 H/s&lt;/strong&gt; vs &lt;strong&gt;87 H/s&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;However, as seen in &lt;strong&gt;Figure 1&lt;/strong&gt;, this efficiency translates into a stark reality for the security horizon of a master password. While Bcrypt provides a formidable defensive wall (estimated at &lt;strong&gt;39 years&lt;/strong&gt; for a given keyspace), Argon2id shifts the goalpost to &lt;strong&gt;268 years&lt;/strong&gt; for that same keyspace. While Bcrypt is "competitive" in its resistance compared to PBKDF2, it is still significantly outclassed by the generational jump in security provided by Argon2id's memory hardness.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Memory Wall of Argon2id
&lt;/h3&gt;

&lt;p&gt;The true advantage of Argon2id is not its throughput, but its &lt;strong&gt;GPU resistance&lt;/strong&gt; through memory hardness. While PBKDF2 scales quickly with hardware power (jumping from 996 H/s on a 1660 Ti to 6271 H/s on a 5080), Argon2id forces a hardware bottleneck.&lt;/p&gt;

&lt;p&gt;On the "High" profile (256MB), the RTX 5080 is roughly &lt;strong&gt;72 times slower&lt;/strong&gt; at cracking Argon2id than it is at cracking PBKDF2, despite the user spending around the same amount of time on verification.&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.amazonaws.com%2Fuploads%2Farticles%2F59vc4fcyzo37w88c6jkw.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.amazonaws.com%2Fuploads%2Farticles%2F59vc4fcyzo37w88c6jkw.png" alt="Hardware Scaling" width="800" height="480"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 2: Hardware scaling factor between GTX 1660 Ti and RTX 5080.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As shown in &lt;strong&gt;Figure 2&lt;/strong&gt;, throwing more modern compute power at the problem yields significantly fewer gains for Argon2id. The more RAM you require, the less effective the attacker's raw compute power becomes, as they quickly hit a VRAM bandwidth and capacity wall.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architectural Anomalies: The 1660 Ti Parity
&lt;/h3&gt;

&lt;p&gt;An unexpected result occurred in the "Low" profile tests on the &lt;strong&gt;GTX 1660 Ti&lt;/strong&gt;, where Argon2id (&lt;strong&gt;360 H/s&lt;/strong&gt;) reached parity with Bcrypt (&lt;strong&gt;346 H/s&lt;/strong&gt;). &lt;/p&gt;

&lt;p&gt;This parity was absent in the other test environments; both the &lt;strong&gt;iGPU&lt;/strong&gt; and the &lt;strong&gt;RTX 5080&lt;/strong&gt; showed Argon2id as roughly twice as slow as Bcrypt at the same level. This suggests that the 1660 Ti represents a specific point of convergence where the computational bottleneck of Bcrypt and the memory bottleneck of Argon2id happen to align, resulting in nearly identical throughput. On shared-memory or ultra-high-compute systems, the memory-hardness of Argon2id becomes the dominant bottleneck much earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For modern applications requiring high security against GPU-based attacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PBKDF2&lt;/strong&gt; is no longer recommended due to its lack of memory requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bcrypt&lt;/strong&gt; is a solid secondary choice but lacks the tuneable memory hardness of newer algorithms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argon2id&lt;/strong&gt; is the superior option. By forcing a significant memory footprint (e.g., 256MB), it effectively neutralizes the massive parallelization advantage of high-end GPUs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my implementation for &lt;a href="https://github.com/treszyk/vaulton-password-manager" rel="noopener noreferrer"&gt;Vaulton&lt;/a&gt;, I provide two tiered options for password security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standard&lt;/strong&gt;: Argon2id (128MB, 3 iterations, 1p) - Balance of performance and security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardened&lt;/strong&gt;: Argon2id (256MB, 4 iterations, 1p) - Maximizing memory hardness for high-value protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These configurations are intended to maximize the computational and physical cost of a brute-force attack, forcing even high-end hardware like the RTX 5080 to operate at a fraction of its potential throughput due to memory bottlenecks. On low-memory mobile devices, higher memory settings (e.g., 256MB) may introduce noticeable latency or fail under constrained environments, so adaptive parameter tuning per device should be considered for commercial products.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;In systems implementing zero-knowledge architecture, the responsibility for performing these heavy KDF calculations shifted to the client-side (e.g., in a browser or mobile app), while the server might only perform a lightweight rehash of authentication verifiers for storage in the database.&lt;/p&gt;

&lt;p&gt;How are you handling the trade-off between client-side performance and high-security KDF parameters? Are there specific edge cases or mobile device limitations you've encountered when requiring significant amounts of RAM for client-side hashing?&lt;/p&gt;

&lt;p&gt;I am particularly interested in feedback about higher security (stronger params) vs user cost (UX degradation) tradeoffs.&lt;/p&gt;

&lt;p&gt;Cover image by Athena Sandrini on &lt;a href="https://www.pexels.com/photo/black-and-gray-motherboard-2582932/" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;, with minor edits.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cryptography</category>
      <category>performance</category>
      <category>thesis</category>
    </item>
    <item>
      <title>Why Do Password Managers Need Your Email?</title>
      <dc:creator>Patryk Sowiński</dc:creator>
      <pubDate>Wed, 25 Mar 2026 15:07:28 +0000</pubDate>
      <link>https://forem.com/treszyk/why-do-password-managers-need-your-email-2onj</link>
      <guid>https://forem.com/treszyk/why-do-password-managers-need-your-email-2onj</guid>
      <description>&lt;p&gt;If you've ever signed up for one of the most popular password managers or even other services, you've probably noticed one commonality between them. They all ask for your email! &lt;/p&gt;

&lt;p&gt;Now, it's standard practice to ask for it, especially for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Newsletters&lt;/li&gt;
&lt;li&gt;  Recovery options&lt;/li&gt;
&lt;li&gt;  Analytics, marketing, and cross-device syncing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;But is it really necessary?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Opaque Identity Alternative
&lt;/h2&gt;

&lt;p&gt;The other design option is to generate an opaque identity for the user, an example would be a randomized string of characters. This choice puts a lot more emphasis on privacy of the user's PII (Personally Identifiable Information) and helps mitigate attacks like credential stuffing based on data leaks from other services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blocking Credential Stuffing
&lt;/h2&gt;

&lt;p&gt;Credential stuffing is an attack method where attackers use old database leaks from other sites to try and break into new ones by testing email and password pairs. This is problematic because many people do reuse usernames/emails and passwords across different websites. But since your username is now a random string, a leaked email for that user doesn't meaningfully help an attacker. It breaks the link between your accounts on different websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducing Target Value
&lt;/h2&gt;

&lt;p&gt;A database without emails is a much less attractive target for hackers. If the provider is breached, the thief doesn't get a valuable list of active emails to spam or sell. This builds more trust in the provider because they are intentionally choosing to hold LESS of your PII.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trade-offs
&lt;/h2&gt;

&lt;p&gt;But like every other design, opaque identity comes with downsides too. That's why while increasing privacy and security this choice puts a lot more responsibility on the user to remember their login information. &lt;/p&gt;

&lt;p&gt;Recovery options are affected too since you can't just send an email. One option is to generate a recovery key on signup that the user has to store somewhere safe. &lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Right Model
&lt;/h2&gt;

&lt;p&gt;Choosing between the email-based or opaque identity ultimately comes down to how secure your system needs to be. A simple forum account might not benefit much from the randomized username, but a password manager would gain more trust in the provider and would block a whole class of attacks. &lt;/p&gt;

&lt;p&gt;In some designs we could go a step further and make the AccountId be the actual GUID of the account from the DB. If this identifier is generated as a sufficiently random value (e.g. a UUIDv4), account enumeration becomes impractical, as guessing valid identifiers is computationally infeasible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;I am currently implementing this opaque identity model as part of my bachelor's thesis project. I'm curious to know what other developers think about this approach. &lt;br&gt;
Is the security and privacy gain of an opaque AccountId worth the extra responsibility on the user? Or is the convenience of an email-based login too good to let go of?&lt;/p&gt;

</description>
      <category>security</category>
      <category>architecture</category>
      <category>privacy</category>
      <category>cybersecurity</category>
    </item>
  </channel>
</rss>
