<?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: Alejandro Cordón</title>
    <description>The latest articles on DEV Community by Alejandro Cordón (@alejandrocordon).</description>
    <link>https://dev.to/alejandrocordon</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%2F1796178%2F94682f46-6643-4e40-a5b9-f13548944af2.jpg</url>
      <title>DEV Community: Alejandro Cordón</title>
      <link>https://dev.to/alejandrocordon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alejandrocordon"/>
    <language>en</language>
    <item>
      <title>Unique Identifiers in Android and iOS: ANDROID_ID, UUID, and Other Strategies</title>
      <dc:creator>Alejandro Cordón</dc:creator>
      <pubDate>Tue, 14 Apr 2026 10:30:42 +0000</pubDate>
      <link>https://dev.to/alejandrocordon/unique-identifiers-in-android-and-ios-androidid-uuid-and-other-strategies-2gl9</link>
      <guid>https://dev.to/alejandrocordon/unique-identifiers-in-android-and-ios-androidid-uuid-and-other-strategies-2gl9</guid>
      <description>&lt;p&gt;In mobile app development, it is common to need a unique identifier that consistently recognizes each device — whether for analytics, personalization, licensing, or usage tracking. However, obtaining and managing that identifier can be tricky due to privacy policies, platform-specific restrictions, and various events that can cause the identifier to change.&lt;br&gt;
In this article, we explore the main ways to identify devices in Android and iOS, with a focus on ANDROID_ID and UUID in iOS. We’ll also look at other available alternatives, discuss their limitations, and review best practices for implementation.&lt;/p&gt;
&lt;h1&gt;
  
  
  Main Native Identifiers
&lt;/h1&gt;
&lt;h2&gt;
  
  
  ANDROID_ID in Android
&lt;/h2&gt;

&lt;p&gt;The value of ANDROID_ID is defined based on three factors: the app’s signing key, the user, and the device. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Each combination of app, user, and device has a unique ANDROID_ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If two apps have different signing keys, even on the same device and same user, they will not share the same ANDROID_ID.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Retrieving it is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Kotlin&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.provider.Settings&lt;/span&gt;

&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;androidId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Secure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contentResolver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Secure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ANDROID_ID&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Java&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.provider.Settings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;androidId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Secure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;getContentResolver&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
    &lt;span class="nc"&gt;Settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Secure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ANDROID_ID&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Behavior:&lt;/strong&gt; It persists across device reboots and system updates. However, it may change after a factory reset, when switching users on multi-user devices, or if the app is signed with a different certificate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; It is not a permanent identifier. During development, tools like Firebase App Distribution use different signing keys, which means the system may treat these versions as separate apps — causing the ANDROID_ID to differ and potentially impacting tests that rely on its consistency.&lt;/p&gt;

&lt;h1&gt;
  
  
  UUID in iOS
&lt;/h1&gt;

&lt;p&gt;iOS does not provide a direct equivalent to &lt;code&gt;ANDROID_ID&lt;/code&gt;. Instead, developers typically use &lt;code&gt;UUID()&lt;/code&gt; (Swift) or &lt;code&gt;NSUUID&lt;/code&gt; (Objective-C) to generate random, universally unique 128-bit identifiers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;UIKit&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuidString&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated UUID: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;
&lt;/span&gt;
&lt;span class="n"&gt;NSUUID&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;uuidObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;NSUUID&lt;/span&gt; &lt;span class="nf"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;NSString&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;uuidString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;uuidObj&lt;/span&gt; &lt;span class="nf"&gt;UUIDString&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;NSLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"Generated UUID: %@"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uuidString&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;Behavior:&lt;/strong&gt; Each call produces a brand-new UUID. It does not persist between app uninstalls or launches unless you explicitly store it (e.g., in the Keychain). There is no single, global “device ID” that iOS exposes by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;identifierForVendor:&lt;/strong&gt; &lt;code&gt;UIDevice.current.identifierForVendor?.uuidString&lt;/code&gt; provides a UUID shared among all apps from the same developer (Team ID). It changes if the user uninstalls all apps from that developer and then reinstalls one. More persistent than a randomly generated UUID, but still mutable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; There is no universal ID in iOS like &lt;code&gt;ANDROID_ID&lt;/code&gt;. To persist an ID over time, developers must store it in a secure location such as the Keychain.&lt;/p&gt;

&lt;h1&gt;
  
  
  Other Ways to Identify Devices
&lt;/h1&gt;

&lt;p&gt;Beyond ANDROID_ID and UUID, there are other methods, each with its own privacy and technical constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advertising Identifiers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Google Advertising ID (GAID) — Android:&lt;/strong&gt; Primarily for advertising and analytics. Users can reset or disable it. Not recommended for long-term device identification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IDFA (Identifier for Advertisers) — iOS:&lt;/strong&gt; Similar to GAID. Since iOS 14.5, it requires the user’s explicit permission via App Tracking Transparency. Can also be reset by the user. Not reliable as a permanent device ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third-Party Service Identifiers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Firebase Installation ID (FID):&lt;/strong&gt; Generated for each app installation and can change if the user uninstalls and reinstalls the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OneSignal Player ID:&lt;/strong&gt; Tied to the subscription in the OneSignal service.&lt;/p&gt;

&lt;p&gt;These are easy to leverage if you already use these platforms, but the ID is associated with an installation, not the physical device.&lt;/p&gt;

&lt;h2&gt;
  
  
  MAC Address and IMEI
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MAC Address:&lt;/strong&gt; Once accessible on both platforms, now strongly restricted for privacy reasons. iOS often returns a placeholder value, and Android restricts access from Marshmallow onward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMEI/MEID:&lt;/strong&gt; The modem identifier in cellular devices. Access is limited to privileged permissions on Android and is not exposed to third-party apps on iOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Device Fingerprinting
&lt;/h2&gt;

&lt;p&gt;Combining multiple device attributes (OS version, model, time zone, language, sensors, etc.) to create a hash that acts as a pseudo-identifier. It doesn’t require access to a specific ID, but it’s not 100% reliable — different devices can share similar fingerprints, and configuration changes can alter the result. It also raises potential privacy concerns.&lt;/p&gt;

&lt;h1&gt;
  
  
  Comparison and Implications
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Persistence
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Identifier  Persistence
ANDROID_ID  Survives reboots and OS updates. Lost after factory reset or user change.
UUID (iOS)  No built-in persistence. Must be stored explicitly.
identifierForVendor Changes if all apps from the same developer are uninstalled.
GAID / IDFA Resettable by the user at any time.
FID / Player ID Tied to app installation, depends on external services.
MAC / IMEI  Restricted or inaccessible on modern OS versions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Unique Identification
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ANDROID_ID:&lt;/strong&gt; Typically unique per device-user pairing, but can change in specific scenarios.&lt;br&gt;
&lt;strong&gt;UUID (iOS):&lt;/strong&gt; Each generation call produces a truly unique value, but iOS provides no default stable device ID.&lt;br&gt;
&lt;strong&gt;Advertising IDs:&lt;/strong&gt; Resettable by the user, dependent on consent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Considerations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Persist a UUID per platform:&lt;/strong&gt; Store a custom-generated UUID in a secure container (Keychain on iOS, EncryptedSharedPreferences or KeyStore on Android).&lt;br&gt;
&lt;strong&gt;Anticipate loss:&lt;/strong&gt; Consider factory resets, app uninstalls, user changes, or permission revocations.&lt;br&gt;
&lt;strong&gt;Follow privacy policies:&lt;/strong&gt; Google and Apple have strict guidelines on tracking. Ensure compliance with user consent and regulations like GDPR and CCPA.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code Examples and Best Practices
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Android: Custom UUID in SharedPreferences
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getOrCreateCustomUUID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sharedPreferences&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSharedPreferences&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"MyAppPrefs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MODE_PRIVATE&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;customUuid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sharedPreferences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_UUID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customUuid&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;customUuid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&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="n"&gt;sharedPreferences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;edit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_UUID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customUuid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&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="n"&gt;customUuid&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This UUID persists unless the user clears the app data or performs a factory reset.&lt;/p&gt;

&lt;h2&gt;
  
  
  iOS: Custom UUID in the Keychain
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;getOrCreateCustomUUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CUSTOM_UUID_KEY"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;existingUuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;KeychainHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"com.myapp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&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="n"&gt;existingUuid&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;newUuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuidString&lt;/span&gt;
        &lt;span class="kt"&gt;KeychainHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"com.myapp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;newUuid&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;newUuid&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;p&gt;The Keychain typically remains intact after uninstalling the app, offering long-term persistence unless the user wipes the entire device.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There is no single, universal device identifier that works across both platforms and survives every scenario. The best strategy is to combine a locally generated UUID with secure storage to recognize the same device in most situations, and handle fallback logic when an identifier changes unexpectedly.&lt;/p&gt;

&lt;p&gt;Always follow Apple and Google’s privacy guidelines, as well as broader data protection regulations like GDPR and CCPA, especially when dealing with personal data.&lt;/p&gt;

&lt;p&gt;Written by Alejandro Cordón — alejandrocordon.com&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>The Day Secrets Were Almost Lost</title>
      <dc:creator>Alejandro Cordón</dc:creator>
      <pubDate>Tue, 14 Apr 2026 07:46:45 +0000</pubDate>
      <link>https://dev.to/alejandrocordon/the-day-secrets-were-almost-lost-3icn</link>
      <guid>https://dev.to/alejandrocordon/the-day-secrets-were-almost-lost-3icn</guid>
      <description>&lt;p&gt;I’m going to tell you how a programmer almost ended up in federal prison. The same kind of prison where they put drug traffickers and arms dealers. And I’m going to tell you why that story has everything to do with something I’m building right now. But that comes at the end. First, listen.&lt;/p&gt;

&lt;p&gt;Sending an encrypted email was legally the same as exporting a missile. The same. An email. A missile. Same legal category. That’s how insane the world was.&lt;br&gt;
Only governments could use strong encryption. You, me, your mother, your neighbor… we all sent emails in the open. Anyone with the right skills could read them. Your boss. Your ex. A bored bureaucrat on a Tuesday afternoon. Anyone.&lt;/p&gt;

&lt;p&gt;And the Senate was cooking up a bill to force backdoors into every communication system. Every single one. So the government could read whatever it wanted whenever it wanted.&lt;/p&gt;

&lt;p&gt;Phil Zimmermann was a programmer. A regular guy. No company. No investors. No legal team. And he saw what was coming.&lt;/p&gt;

&lt;p&gt;So he did something the government considered a criminal act: he wrote a program that encrypted emails and uploaded it to the internet. Free. For everyone.&lt;/p&gt;

&lt;p&gt;It was called Pretty Good Privacy. PGP. Within weeks it was on servers across half the planet. Activists used it. Journalists used it. Regular people used it so their emails would be their own.&lt;/p&gt;

&lt;p&gt;And then the FBI knocked on his door.&lt;/p&gt;

&lt;p&gt;Three years of criminal investigation. Arms trafficking. That’s what his file said. Because a program that encrypted emails was classified exactly the same as a missile.&lt;/p&gt;

&lt;p&gt;One man alone. No money. No lawyers. Against the entire federal government of the United States.&lt;/p&gt;

&lt;p&gt;His crime? Believing that your conversations belong to you.&lt;/p&gt;

&lt;p&gt;He said two things during those years that should be tattooed on the forehead of every Silicon Valley CEO.&lt;/p&gt;

&lt;p&gt;The first: “If privacy is outlawed, only outlaws will have privacy.”&lt;/p&gt;

&lt;p&gt;The second will send a chill down your spine: “Show me someone who has nothing to hide and I’ll show you someone who is either extremely boring or a complete exhibitionist.”&lt;/p&gt;

&lt;p&gt;Twenty-five years before Snowden. With less filter and more bite.&lt;/p&gt;

&lt;p&gt;In 1996 they dropped the charges. But PGP was still illegal to export. And here comes the move that changed everything.&lt;/p&gt;

&lt;p&gt;Zimmermann printed the entire source code in a book. Paper. Ink. Binding. An actual book. Why? Because books are protected by freedom of speech. You can’t ban the export of a book.&lt;/p&gt;

&lt;p&gt;Someone bought it. Took it outside the United States. Scanned it. Compiled it. And distributed it as free software.&lt;/p&gt;

&lt;p&gt;Military-grade encryption. Distributed as a paperback. Perfectly legal. Checkmate.&lt;/p&gt;

&lt;p&gt;Zimmermann won. Strong encryption is legal today. AES-256, military-grade, fits in your phone. The technology exists and it’s more powerful than ever.&lt;/p&gt;

&lt;p&gt;But most apps you use every day hold the keys to your encryption themselves. Which is exactly like putting a lock on your door and taping the key to the mailbox.&lt;/p&gt;

&lt;p&gt;Zimmermann didn’t give the world anything new. He gave back something that had always belonged to it.&lt;/p&gt;

&lt;p&gt;He almost went to federal prison so you could have secrets. The question is: are you protecting them or handing them over to the first app that asks for permission?&lt;/p&gt;

&lt;p&gt;In Latin, there is a single-word command meaning keep silent: sile. The silence to think in peace. To write what you feel without anyone looking over your shoulder. To hold your ideas until they’re ready. Zimmermann fought to make that silence a right. And I’m building something so you can exercise it. It’s called Sile. But I’m not going to tell you more today. Not yet. That will come.&lt;/p&gt;

&lt;p&gt;Alejandro Cordón. alejandrocordon.com&lt;/p&gt;

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