<?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: Dima Ulyanov</title>
    <description>The latest articles on DEV Community by Dima Ulyanov (@dima_ulyanov_787bd1026dae).</description>
    <link>https://dev.to/dima_ulyanov_787bd1026dae</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%2F3965197%2Fa45fcb36-397a-489e-84e5-8c85b54afecf.png</url>
      <title>DEV Community: Dima Ulyanov</title>
      <link>https://dev.to/dima_ulyanov_787bd1026dae</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dima_ulyanov_787bd1026dae"/>
    <language>en</language>
    <item>
      <title>I built a working SSL certificate replacement using Certificateless Public Key Cryptography (CL-PKC) – live demo inside</title>
      <dc:creator>Dima Ulyanov</dc:creator>
      <pubDate>Tue, 16 Jun 2026 08:54:40 +0000</pubDate>
      <link>https://dev.to/dima_ulyanov_787bd1026dae/i-built-a-working-ssl-certificate-replacement-using-certificateless-public-key-cryptography-37af</link>
      <guid>https://dev.to/dima_ulyanov_787bd1026dae/i-built-a-working-ssl-certificate-replacement-using-certificateless-public-key-cryptography-37af</guid>
      <description>&lt;p&gt;Hey,&lt;/p&gt;

&lt;p&gt;I've been building a proof-of-concept called 0Cert that replaces &lt;br&gt;
SSL certificates with Certificateless Public Key Cryptography (CL-PKC).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The core problem with SSL:&lt;/strong&gt;&lt;br&gt;
~150 Certificate Authorities can issue certificates for any domain. &lt;br&gt;
One compromised CA breaks trust for the entire web. We've seen this &lt;br&gt;
happen (DigiNotar, Comodo, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How 0Cert works:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of CAs, a Key Generation Center (KGC) issues a &lt;em&gt;partial&lt;/em&gt; &lt;br&gt;
private key for your domain. You generate your own ECDH P-256 secret &lt;br&gt;
locally. You combine them into a full private key that the KGC never &lt;br&gt;
sees.&lt;/p&gt;

&lt;p&gt;`partialKey  = KGC.derive(masterSecret, identity)  ← KGC knows this&lt;/p&gt;

&lt;p&gt;userSecret  = ECDH.random()                        ← never leaves device&lt;/p&gt;

&lt;p&gt;fullPrivKey = combine(partialKey, userSecret)       ← nobody else has this`&lt;/p&gt;

&lt;p&gt;Even a fully compromised KGC cannot decrypt user traffic. This is &lt;br&gt;
based on the Al-Riyami &amp;amp; Paterson 2003 CL-PKC scheme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live KGC server: &lt;a href="https://kgc.0cert.io" rel="noopener noreferrer"&gt;https://kgc.0cert.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Web app (works on any device): &lt;a href="https://app.0cert.io" rel="noopener noreferrer"&gt;https://app.0cert.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;iOS browser app (Swift) that detects 0Cert sites via DNS TXT records&lt;/li&gt;
&lt;li&gt;npm middleware: &lt;code&gt;npm install 0cert-middleware&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;All code: &lt;a href="https://github.com/0cert" rel="noopener noreferrer"&gt;https://github.com/0cert&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How site verification works:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Site owner adds DNS TXT record:&lt;/p&gt;

&lt;p&gt;TXT @ ibc-kgc=&lt;a href="https://kgc.0cert.io" rel="noopener noreferrer"&gt;https://kgc.0cert.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installs middleware:&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zerocert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mysite.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fullPrivKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Browser checks DNS → calls /.well-known/0cert → shows verified badge. &lt;br&gt;
No certificate chain. No CA involved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest limitations (security folks will ask):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Browsers don't support this natively — runs alongside SSL for now&lt;/li&gt;
&lt;li&gt;KGC trust problem — you're replacing CA trust with KGC trust. 
The difference: KGC provably can't decrypt (math), CAs just 
promise they won't fake certs (policy)&lt;/li&gt;
&lt;li&gt;My implementation uses HMAC-SHA256 key derivation instead of 
actual Weil/Tate pairings over elliptic curves — the trust model 
is cryptographically sound, the underlying math is simplified&lt;/li&gt;
&lt;li&gt;No IETF RFC yet&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The path to browser adoption:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DNS TXT records are already trusted by browsers. DANE (RFC 6698) &lt;br&gt;
proved the concept. The missing piece is a standardized KGC protocol &lt;br&gt;
and browser-native verification — which starts with a working &lt;br&gt;
implementation people can test.&lt;/p&gt;

&lt;p&gt;Would love feedback from the security community, especially on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The KGC trust model vs CA trust model&lt;/li&gt;
&lt;li&gt;Whether the CL-PKC approach is worth pursuing seriously&lt;/li&gt;
&lt;li&gt;Known attacks on this model I should address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://0cert.io" rel="noopener noreferrer"&gt;https://0cert.io&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/0cert" rel="noopener noreferrer"&gt;https://github.com/0cert&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>cryptography</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Key point in Do List 100 v2.0 Brings Due Dates, Auto-Progress and Full iPad &amp; Mac Support</title>
      <dc:creator>Dima Ulyanov</dc:creator>
      <pubDate>Tue, 02 Jun 2026 18:47:24 +0000</pubDate>
      <link>https://dev.to/dima_ulyanov_787bd1026dae/key-point-in-do-list-100-v20-brings-due-dates-auto-progress-and-full-ipad-mac-support-1b49</link>
      <guid>https://dev.to/dima_ulyanov_787bd1026dae/key-point-in-do-list-100-v20-brings-due-dates-auto-progress-and-full-ipad-mac-support-1b49</guid>
      <description>&lt;p&gt;Hi everybody. &lt;br&gt;
We have created this app around two months and this is third version with fixed bugs. Now it is amazing app that synchronization your tasks throughs iPhone iPad Mac via iCloud with no Sign In! And in pocket you will already have a useful notes. &lt;/p&gt;

&lt;p&gt;It was a huge code work. Hours and hours. Such a pleasure.&lt;/p&gt;

&lt;p&gt;What I want to note here for you fellas, we were going from these scheme:&lt;/p&gt;

&lt;h2&gt;
  
  
  What's really happening
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The self-overwrite loop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User edits subtask title
        ↓
onChange fires → scheduleSave() → debounce 1s
        ↓
...debounce fires → DataManager.save() writes todos.json to iCloud
        ↓
NSMetadataQuery detects file change on disk
        ↓                         ↑
        └── todosChanged() ───────┘
              ↓
        taskManager.loadTodos()
              ↓
        self.todos = loadedTodos   ← 💥 replaces entire array mid-edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The core problem is that &lt;code&gt;NSMetadataQuery&lt;/code&gt; watches the file at the OS level. It has &lt;strong&gt;no concept of who made the change&lt;/strong&gt; — your own app writing the file looks identical to another device syncing a change over iCloud. So every save you make triggers a reload that cancels whatever the user is currently doing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why subtask titles are worst affected
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;TextField&lt;/code&gt; bound to &lt;code&gt;$subtask.title&lt;/code&gt; is live — it reflects the array value character by character. The moment &lt;code&gt;self.todos = loadedTodos&lt;/code&gt; runs, SwiftUI throws away the in-memory array and rebuilds from the freshly decoded JSON. If the save hasn't happened yet (debounce still counting down), the loaded file has the &lt;em&gt;old&lt;/em&gt; title, and the field visually snaps back.&lt;/p&gt;

&lt;p&gt;Progress sliders have the same issue but it's less noticeable because a slider value is a &lt;code&gt;Double&lt;/code&gt; — the snap-back is a jump rather than disappearing characters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why it only shows up on real devices
&lt;/h3&gt;

&lt;p&gt;The simulator runs everything on the same Mac so iCloud writes are near-instant and the race window is tiny. On a real device the file system is slower and iCloud sync adds latency, making the timing gap between "user is editing" and "reload fires" much more visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three fixes needed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fix 1 — Ignore self-triggered reloads in &lt;code&gt;DataManager&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Track a &lt;code&gt;isSavingLocally&lt;/code&gt; flag. Set it &lt;code&gt;true&lt;/code&gt; before writing, &lt;code&gt;false&lt;/code&gt; after. In &lt;code&gt;todosChanged()&lt;/code&gt; skip the reload if the flag is set. This stops your own saves from triggering reloads entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 2 — Add an &lt;code&gt;isEditing&lt;/code&gt; guard in &lt;code&gt;TaskManager&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Expose a simple &lt;code&gt;isUserEditing: Bool&lt;/code&gt; flag that &lt;code&gt;ContentView&lt;/code&gt; sets to &lt;code&gt;true&lt;/code&gt; when a &lt;code&gt;TextField&lt;/code&gt; is focused and &lt;code&gt;false&lt;/code&gt; on &lt;code&gt;onSubmit&lt;/code&gt;/focus loss. &lt;code&gt;loadTodos()&lt;/code&gt; checks this flag and skips the reload if the user is mid-edit, queuing it for after they finish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 3 — Debounce the reload too, not just the save&lt;/strong&gt;&lt;br&gt;
Right now saves are debounced (1 second) but reloads are instant. If a remote change does arrive legitimately, it should also wait briefly before replacing the array — giving any in-flight edits time to be committed first. A 0.5-second debounce on &lt;code&gt;todosChanged()&lt;/code&gt; is enough.&lt;/p&gt;

&lt;p&gt;TO THIS: &lt;/p&gt;

&lt;p&gt;Own save    → flag set    → reload blocked entirely&lt;br&gt;
Mid-edit    → isEditing   → reload deferred until focus lost&lt;br&gt;&lt;br&gt;
Remote sync → debounced   → reload waits 0.5s before replacing array&lt;/p&gt;

&lt;p&gt;Interesting in your opinions. &lt;/p&gt;

&lt;p&gt;[LINK TO THE APP(&lt;a href="https://apps.apple.com/us/app/do-list-100/id6758045201)" rel="noopener noreferrer"&gt;https://apps.apple.com/us/app/do-list-100/id6758045201)&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>apple</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
