<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged encryption</title>
<link>https://coderlegion.com/tag/encryption</link>
<description>Powered by Question2Answer</description>
<item>
<title>Perenio Peifc01 IP Camera and Android Application Analysis</title>
<link>https://coderlegion.com/28970/perenio-peifc01-ip-camera-and-android-application-analysis</link>
<description>&lt;h2 id=&quot;initial-discovery&quot;&gt;Initial Discovery&lt;/h2&gt;
&lt;p&gt;Using &lt;a rel=&quot;nofollow&quot; href=&quot;https://codeshare.frida.re/@KostasEreksonas/crypto-discovery/&quot;&gt;my custom Frida script&lt;/a&gt; for cryptographic method detection in Android applications, I captured Java Cipher class doing a decryption operation, along with it's stack trace:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;objectId&quot;: &quot;Cipher-30236645&quot;,
  &quot;timestamp&quot;: 1789412643454,
  &quot;lastSeen&quot;: 1789412643488,
  &quot;instanceOverload&quot;: &quot;1. [Cipher.getInstance(java.lang.String) -&amp;gt; static Cipher]&quot;,
  &quot;transformation&quot;: &quot;AES/CBC/PKCS5Padding&quot;,
  &quot;algorithm&quot;: &quot;AES/CBC/PKCS5Padding&quot;,
  &quot;runtimeClass&quot;: &quot;javax.crypto.Cipher&quot;,
  &quot;providerName&quot;: &quot;AndroidOpenSSL&quot;,
  &quot;providerVersion&quot;: 1,
  &quot;providerInfo&quot;: &quot;Android's OpenSSL-backed security provider&quot;,
  &quot;providerClass&quot;: &quot;com.android.org.conscrypt.OpenSSLProvider&quot;,
  &quot;updateInputs&quot;: [],
  &quot;updateInputsLen&quot;: [],
  &quot;updateOutputs&quot;: [],
  &quot;updateOutputsLen&quot;: [],
  &quot;initOverload&quot;: &quot;6. [Cipher.init(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) -&amp;gt; void]&quot;,
  &quot;opmode&quot;: 2,
  &quot;opmodeString&quot;: &quot;DECRYPT&quot;,
  &quot;blockSize&quot;: 16,
  &quot;keyClass&quot;: &quot;javax.crypto.spec.SecretKeySpec&quot;,
  &quot;keyAlgorithm&quot;: &quot;AES&quot;,
  &quot;keyFormat&quot;: &quot;RAW&quot;,
  &quot;keyBytesHex&quot;: &quot;4bf14ea15d7bd3bbfcf9b7d9acc6db5c&quot;,
  &quot;keyBytesString&quot;: &quot;K.N.]{.........\\&quot;,
  &quot;keyBytesFingerprint&quot;: &quot;32862b80:16&quot;,
  &quot;parameterClass&quot;: &quot;javax.crypto.spec.IvParameterSpec&quot;,
  &quot;iv&quot;: &quot;000000000000000000000000000000&quot;,
  &quot;ivFingerprint&quot;: &quot;69691905:16&quot;,
  &quot;secureRandom&quot;: &quot;java.security.SecureRandom&quot;,
  &quot;finalOverload&quot;: &quot;2. [Cipher.doFinal(byte[] input) -&amp;gt; byte[]]&quot;,
  &quot;bytesWritten&quot;: 96,
  &quot;input&quot;: &quot;7c354a11ebcff3abe4b3c1c359cb16c14a1685851abaca3fd80b2cb8ba1b423f398944c108b2ba6096d43fb0317c5c17 ... [64 more bytes]&quot;,
  &quot;output&quot;: &quot;{\&quot;commonPrefs\&quot;:{\&quot;display_rate_us_after\&quot;:0,\&quot;permi ... [48 more bytes]&quot;,
  &quot;outputFingerprint&quot;: &quot;a29ad7a9:96&quot;,
  &quot;stackTrace&quot;: [
    &quot;java.lang.Throwable&quot;,
    &quot;at javax.crypto.Cipher.doFinal(Native Method)&quot;,
    &quot;at se.simbio.encryption.Encryption.decrypt(Encryption.java:179)&quot;,
    &quot;at se.simbio.encryption.Encryption.decryptOrNull(Encryption.java:193)&quot;,
    &quot;at com.perenio.data.util.EncryptionUtils.decrypt(EncryptionUtils.kt:21)&quot;,
    &quot;at com.perenio.data.local.sharedpreference.base.AbsEncryptPreferencesProvider.getStringDecrypt(AbsEncryptPreferencesProvider.kt:15)&quot;,
    &quot;at com.perenio.data.local.sharedpreference.base.AbsEncryptPreferencesProvider.getStringDecrypt$default(AbsEncryptPreferencesProvider.kt:13)&quot;,
    &quot;at com.perenio.data.local.sharedpreference.SharedPreferencesProvider.&amp;lt;init&amp;gt;(SharedPreferencesProvider.kt:149)&quot;,
    &quot;at com.perenio.smarthome.di.module.data.SharedPreferencesModule.provideSharedPreferencesProvider(SharedPreferencesModule.kt:25)&quot;,
    &quot;at com.perenio.smarthome.di.module.data.SharedPreferencesModule_ProvideSharedPreferencesProviderFactory.provideSharedPreferencesProvider(SharedPreferencesModule_ProvideSharedPreferencesProviderFactory.java:56)&quot;,
    &quot;at com.perenio.smarthome.di.module.data.SharedPreferencesModule_ProvideSharedPreferencesProviderFactory.get(SharedPreferencesModule_ProvideSharedPreferencesProviderFactory.java:44)&quot;,
    &quot;at com.perenio.smarthome.di.module.data.SharedPreferencesModule_ProvideSharedPreferencesProviderFactory.get(SharedPreferencesModule_ProvideSharedPreferencesProviderFactory.java:14)&quot;,
    &quot;at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)&quot;,
    &quot;at com.perenio.smarthome.di.module.data.SectionsModule_ProvideUserSectionFactory.get(SectionsModule_ProvideUserSectionFactory.java:68)&quot;,
    &quot;at com.perenio.smarthome.di.module.data.SectionsModule_ProvideUserSectionFactory.get(SectionsModule_ProvideUserSectionFactory.java:19)&quot;,
    &quot;at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)&quot;,
    &quot;at com.perenio.smarthome.di.component.DaggerAppComponent$AppComponentImpl.synchronizeSubscriptionsUseCase(DaggerAppComponent.java:2416)&quot;,
    &quot;at com.perenio.smarthome.di.component.DaggerAppComponent$AppComponentImpl.injectPerenioApp(DaggerAppComponent.java:3815)&quot;,
    &quot;at com.perenio.smarthome.di.component.DaggerAppComponent$AppComponentImpl.inject(DaggerAppComponent.java:3036)&quot;,
    &quot;at com.perenio.smarthome.PerenioApp.onCreate(PerenioApp.kt:47)&quot;,
    &quot;at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1385)&quot;,
    &quot;at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7830)&quot;,
    &quot;at android.app.ActivityThread.handleBindApplication(Native Method)&quot;,
    &quot;at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)&quot;,
    &quot;at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2546)&quot;,
    &quot;at android.os.Handler.dispatchMessage(Handler.java:110)&quot;,
    &quot;at android.os.Looper.loopOnce(Looper.java:248)&quot;,
    &quot;at android.os.Looper.loop(Looper.java:338)&quot;,
    &quot;at android.app.ActivityThread.main(ActivityThread.java:9068)&quot;,
    &quot;at java.lang.reflect.Method.invoke(Native Method)&quot;,
    &quot;at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:596)&quot;,
    &quot;at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)\n&quot;
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;cryptography-implementation-analysis&quot;&gt;Cryptography Implementation Analysis&lt;/h2&gt;
&lt;h3 id=&quot;pulling-android-application-to-host&quot;&gt;Pulling Android Application to Host&lt;/h3&gt;
&lt;p&gt;Name of the Android application is &lt;code&gt;com.perenio.smarthome&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;List relevant packages:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;adb shell pm list packages | grep &amp;lt;package-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Get full path name for the package with &lt;code&gt;adb shell pm path &amp;lt;package-name&amp;gt;&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;package:/data/app/~~s-&amp;lt;base64-string&amp;gt;/&amp;lt;package-name&amp;gt;-n_K_-&amp;lt;base64-string&amp;gt;/base.apk
package:/data/app/~~s-&amp;lt;base64-string&amp;gt;/&amp;lt;package-name&amp;gt;-n_K_-&amp;lt;base64-string&amp;gt;/split_asset_pack.apk
package:/data/app/~~s-&amp;lt;base64-string&amp;gt;/&amp;lt;package-name&amp;gt;-n_K_-&amp;lt;base64-string&amp;gt;/split_config.arm64_v8a.apk
package:/data/app/~~s-&amp;lt;base64-string&amp;gt;/&amp;lt;package-name&amp;gt;-n_K_-&amp;lt;base64-string&amp;gt;/split_config.en.apk
package:/data/app/~~s-&amp;lt;base64-string&amp;gt;/&amp;lt;package-name&amp;gt;-n_K_-&amp;lt;base64-string&amp;gt;/split_config.xxhdpi.apk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Core application logic is stored in &lt;code&gt;base.apk&lt;/code&gt; with assets and configs stored in separate .apk files. For the purposes of current research, only the base application file was analyzed.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pull the &lt;code&gt;base.apk&lt;/code&gt; to host machine:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;adb pull /data/app/~~s-&amp;lt;base64-string&amp;gt;/&amp;lt;package-name&amp;gt;-n_K_-&amp;lt;base64-string&amp;gt;/base.apk
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/KostasEreksonas/android_analysis/blob/main/scripts/pull_application&quot;&gt;A shell script that automates package pulling process can be found by following this link&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;application-analysis-with-jadx-and-frida&quot;&gt;Application Analysis with JADX and Frida&lt;/h3&gt;
&lt;p&gt;This section covers analysis of Perenio application's data encryption and decryption methods. Both static analysis with JADX and dynamic analysis using Frida were performed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;One important thing to note:&lt;/em&gt;&lt;/strong&gt; the described encryption method is a local-only encryption method, i.e. it only protects data that is at rest in local storage. Data transmitted via network is protected by TLSv1.3 sessions and SSL certificates pinned into Perenio app.&lt;/p&gt;
&lt;p&gt;Searching for &lt;code&gt;se.simbio.encryption.Encryption&lt;/code&gt; in Jadx-gui leads to the decompiled code of the &lt;code&gt;Encryption&lt;/code&gt; class (whose scope is set to public).&lt;/p&gt;
&lt;p&gt;The class has &lt;code&gt;getDefault(String str, String str2, byte[] bArr) { ... }&lt;/code&gt; method that creates an object of &lt;code&gt;Builder&lt;/code&gt; class, responsible for providing information necessary to construct key and initialization vector (IV) for AES encryption:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=5423388843531633055&quot; alt=&quot;Encryption.getDefault() method&quot;&gt;&lt;/p&gt;
&lt;p&gt;This method is called from &lt;code&gt;com.perenio.data.util.EncryptionUtils&lt;/code&gt; class and gets hardcoded key and salt values provided as arguments:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=14475187547038655165&quot; alt=&quot;Encryption.getDefault() in EncryptionUtils&quot;&gt;&lt;/p&gt;
&lt;p&gt;The builder method itself builds a key from provided information and has setters and getters for every private variable:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=1239275231021999193&quot; alt=&quot;Builder method&quot;&gt;&lt;/p&gt;
&lt;p&gt;Overloading the &lt;code&gt;getDefaultBuilder&lt;/code&gt; method (along with &lt;code&gt;decrypt&lt;/code&gt; method) using Frida discloses that the following information is being received during Perenio application's initialization sequence:&lt;/p&gt;
&lt;p&gt;During the app initialization stage, Frida overloads for &lt;code&gt;getDefaultBuilder&lt;/code&gt; and &lt;code&gt;decrypt&lt;/code&gt; methods captured the following information about building a key and IV for AES decryption operation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;threadId&quot;: &quot;2&quot;,
  &quot;builder&quot;: {
    &quot;algorithm&quot;: &quot;AES/CBC/PKCS5Padding&quot;,
    &quot;modeBase64&quot;: 0,
    &quot;charsetName&quot;: &quot;UTF8&quot;,
    &quot;digestAlgorithm&quot;: &quot;SHA1&quot;,
    &quot;iterationCount&quot;: 1,
    &quot;iv&quot;: &quot;00000000000000000000000000000000&quot;,
    &quot;ivParameterSpec&quot;: null,
    &quot;key&quot;: &quot;A45BE7EF0543D36B4F68DvD3EF4013D4&quot;,
    &quot;keyAlgorithm&quot;: &quot;AES&quot;,
    &quot;keyLength&quot;: 128,
    &quot;salt&quot;: &quot;BDBA982FAF389694&quot;,
    &quot;secretKeyType&quot;: &quot;PBKDF2WithHmacSHA1&quot;,
    &quot;secureRandom&quot;: null,
    &quot;secureRandomAlgorithm&quot;: &quot;SHA1PRNG&quot;
  },
  &quot;getDefaultInfo&quot;: {
    &quot;key&quot;: &quot;A45BE7EF0543D36B4F68DvD3EF4013D4&quot;,
    &quot;salt&quot;: &quot;BDBA982FAF389694&quot;,
    &quot;defaultKey&quot;: &quot;00000000000000000000000000000000&quot;
  },
  &quot;encrypted&quot;: &quot;fDVKEevP86vks8HDWcsWwUoWhYUauso/2AssuLobQj85iUTBCLK6YJbUP7AxfFwXHjKn3F3URNgh\n/2SvLbPOPqS3wos0B9h8m/Q9jtfCVvEt3TqiLY0dSeff12q/2BmDRKpBQYHFeO+F8UKtMuNdoA==\n    &quot;,
  &quot;hashTheKeyInfo&quot;: {
    &quot;keyPlaintext&quot;: &quot;A45BE7EF0543D36B4F68DvD3EF4013D4&quot;,
    &quot;keyHashed&quot;: &quot;zb6XIjgHtuii5dEcQuiY/8QFluA\n&quot;
  },
  &quot;SKFGetInstance&quot;: {
    &quot;secretKeyType&quot;: &quot;PBKDF2WithHmacSHA1&quot;,
    &quot;providerName&quot;: &quot;BC&quot;,
    &quot;providerVersion&quot;: 1.77,
    &quot;providerInfo&quot;: &quot;BouncyCastle Security Provider v1.77&quot;
  },
  &quot;SKFGenerateSecret&quot;: {
    &quot;algorithm&quot;: &quot;PBKDF2WithHmacSHA1&quot;,
    &quot;PBEKeySpecInfo&quot;: {
      &quot;iterationCount&quot;: 1,
      &quot;keyLength&quot;: 128,
      &quot;password&quot;: &quot;zb6XIjgHtuii5dEcQuiY/8QFluA\n&quot;,
      &quot;salt&quot;: &quot;BDBA982FAF389694&quot;
    },
    &quot;secretKey&quot;: &quot;4bf14ea15d7bd3bbfcf9b7d9acc6db5c&quot;
  },
  &quot;SKSInit&quot;: {
    &quot;key&quot;: &quot;4bf14ea15d7bd3bbfcf9b7d9acc6db5c&quot;,
    &quot;Algorithm&quot;: &quot;AES&quot;
  },
  &quot;getSecretKeyInfo&quot;: {
    &quot;algorithm&quot;: &quot;AES&quot;,
    &quot;keyMaterial&quot;: &quot;4bf14ea15d7bd3bbfcf9b7d9acc6db5c&quot;
  },
  &quot;cryptoInitInfo&quot;: {
    &quot;opmode&quot;: 2,
    &quot;opmodeString&quot;: &quot;DECRYPT&quot;,
    &quot;key&quot;: {
      &quot;keyClass&quot;: &quot;javax.crypto.spec.SecretKeySpec&quot;,
      &quot;keyAlgorithm&quot;: &quot;AES&quot;,
      &quot;keyFormat&quot;: &quot;RAW&quot;,
      &quot;keyEncoded&quot;: &quot;4bf14ea15d7bd3bbfcf9b7d9acc6db5c&quot;
    },
    &quot;parameters&quot;: {
      &quot;parameterClass&quot;: &quot;javax.crypto.spec.IvParameterSpec&quot;,
      &quot;parameterValue&quot;: &quot;00000000000000000000000000000000&quot;
    },
    &quot;secureRandom&quot;: {
      &quot;secureRandomClass&quot;: &quot;java.security.SecureRandom&quot;,
      &quot;secureRandomAlgorithm&quot;: &quot;SHA1PRNG&quot;,
      &quot;secureRandomProvider&quot;: &quot;AndroidOpenSSL version 1.0&quot;
    }
  },
  &quot;decrypted&quot;: {
    &quot;commonPrefs&quot;: {
      &quot;display_rate_us_after&quot;: 0,
      &quot;permission_event_severity&quot;: &quot;event&quot;
    },
    &quot;devicePrefs&quot;: {}
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Secret key for both &lt;code&gt;encrypt&lt;/code&gt; and &lt;code&gt;decrypt&lt;/code&gt; operations is built upon a hardcoded key in &lt;code&gt;hashTheKey&lt;/code&gt; method:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=13566060183327577280&quot; alt=&quot;Hashing function of hardcoded key&quot;&gt;&lt;/p&gt;
&lt;p&gt;As an example, let's take &lt;code&gt;Encryption.encrypt()&lt;/code&gt; method:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=7719426748073445138&quot; alt=&quot;Encryption.encrypt() method&quot;&gt;&lt;/p&gt;
&lt;p&gt;This method works roughly as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The key for &lt;code&gt;getSecretKey&lt;/code&gt; method is prepared by &lt;code&gt;hashTheKey&lt;/code&gt; method:&lt;ul&gt;
&lt;li&gt;MessageDigest object gets instantiated with a digest algorithm (SHA1 in collected samples).&lt;/li&gt;
&lt;li&gt;The digest object gets updated with hardcoded key (encoded with &lt;code&gt;utf-8&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Hash computation is finished with a call to &lt;code&gt;digest()&lt;/code&gt; method, the final hash being encoded to Base64 string (with NO_PADDING flag enabled) and converted to a char array.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getSecretKey&lt;/code&gt; method instantiates &lt;code&gt;SecretKeyFactory&lt;/code&gt; object:&lt;ul&gt;
&lt;li&gt;Type of the final secret key is set as &lt;code&gt;PBKDF2WithHmacSHA1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PBEKeySpec&lt;/code&gt; is instantiated with the following parameters:&lt;ul&gt;
&lt;li&gt;Iteration count: 1.&lt;/li&gt;
&lt;li&gt;Key length: 128-bit.&lt;/li&gt;
&lt;li&gt;Password: output from &lt;code&gt;hashTheKey&lt;/code&gt; method (PBKDF2 password represented as a Java character array).&lt;/li&gt;
&lt;li&gt;Salt: a value that is also hardcoded into Perenio Android application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;generateSecret&lt;/code&gt; method computes secret key from the previously listed parameters. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Java &lt;code&gt;Cipher&lt;/code&gt; object is instantiated with the transformation &lt;code&gt;AES/CBC/PKCS5Padding&lt;/code&gt; and is initialized with:&lt;ul&gt;
&lt;li&gt;Operation mode (opmode):&lt;ul&gt;
&lt;li&gt;1 = encryption&lt;/li&gt;
&lt;li&gt;2 = decryption.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Secret key.&lt;/li&gt;
&lt;li&gt;Initialization vector (IV).&lt;/li&gt;
&lt;li&gt;Secure random (this field is initialized but not used).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Message is encrypted using &lt;code&gt;Cipher.doFinal()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;Encryption.decrypt()&lt;/code&gt; method follows the same Cipher pattern, just with &lt;code&gt;opmode = 2&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=11721607375419126935&quot; alt=&quot;Encryption.decrypt() method&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;./perenio.js&quot;&gt;Javascript code for this Frida overload is available in this repository as perenio.js.&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;./pythonImplementations/crypto.py&quot;&gt;Python reimplementation of the described encryption method is available at pythonImplementations/crypto.py.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sample outputs of dynamic analysis script &lt;a rel=&quot;nofollow&quot; href=&quot;./sampleLogs/&quot;&gt;can be found in sampleLogs directory&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;security-findings&quot;&gt;Security Findings&lt;/h3&gt;
&lt;p&gt;A few notable considerations regarding the cryptographic methods used in the Perenio Android application:  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Key and salt values are hardcoded into the Perenio Android application.&lt;/li&gt;
&lt;li&gt;Initialization vector (IV) is initialized as a 16 byte long value of all-zeros.&lt;/li&gt;
&lt;li&gt;Having a static key combined with all-zero IV makes AES-CBC deterministic - same plaintext inputs produce the same ciphertext outputs.&lt;/li&gt;
&lt;li&gt;SecureRandom is instantiated but is never used to derive IV.&lt;/li&gt;
&lt;li&gt;Password-Based Key Derivation Function 2 (PBKDF2) has an iteration count of &lt;strong&gt;&lt;em&gt;1&lt;/em&gt;&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;PBKDF2 iteration count determines how many times the hashing process of key material should be repeated.&lt;/li&gt;
&lt;li&gt;On the first iteration, input key is mixed with the salt and hashed.&lt;/li&gt;
&lt;li&gt;Subsequent iterations takes hash output of previous iteration and re-hashes it with the same method.&lt;/li&gt;
&lt;li&gt;As a final step, outputs of all iterations are combined (typically with a bitwise XOR) to produce the final encryption key.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html&quot;&gt;OWASP recommends 1,400,000 iterations for PBKDF2-HMAC-SHA1 (legacy) key derivation function&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Perenio app's crypto implementation repeats the hashing process exactly 1 time, which, combined with hardcoded key, salt and all-zero IV provide no real security on the local data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Key, derived with the aforementioned parameters, is being reused for subsequent local cryptographic operations.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; This is an app-only encryption method. Data in-transit is still being guarded by TLSv1.3, as well as SSL certificates pinned within Perenio Android application.&lt;/p&gt;
&lt;p&gt;Given the points listed above, the in-app security layer reads more like an obfuscation layer rather than true random, non-deterministic encryption method.&lt;/p&gt;
&lt;h2 id=&quot;login-sequence&quot;&gt;Login Sequence&lt;/h2&gt;
&lt;p&gt;Login sequence was intercepted using Mitmproxy and captured with Wireshark for analysis. However, network communications between Perenio Android application and the vendor's remote servers have a couple of protections:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;TLSv1.3 session is negotiated before any data reaches the network.&lt;/li&gt;
&lt;li&gt;Perenio Android application has SSL pinning enabled, meaning that only devices having Perenio's own CA certificates are trusted with the plain text data.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Tricking Android device into trusting my proxy for establishing TLSv1.3 session with it is as simple as injecting Mitmproxy's CA certificates onto Android system trust store (&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/KostasEreksonas/android_analysis/blob/main/scripts/inject_certificates&quot;&gt;Bash automation script for this process can be found here&lt;/a&gt;). For pinned certificate bypass, Frida objection with &lt;code&gt;android sslpinning disable&lt;/code&gt; script was used.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; For dynamic analysis with Frida, &lt;code&gt;frida-server&lt;/code&gt; must be loaded and run on a target device as a daemon, so that a Frida client on host machine could have a harness that can be attached to a process for inspection and modification purposes.&lt;/p&gt;
&lt;p&gt;A quick description of the algorithm used for capturing plain text communication between Perenio Android app and vendor's servers might be this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Injecting Mitmproxy's CA certificate onto Android system trust store.&lt;/li&gt;
&lt;li&gt;Push &lt;code&gt;frida-server-&amp;lt;version&amp;gt;-android-arm64&lt;/code&gt; onto a rooted Android device or an emulator via &lt;code&gt;adb&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start &lt;code&gt;frida-server&lt;/code&gt; on Android device.&lt;/li&gt;
&lt;li&gt;Set up Wi-Fi proxy on Android device to point at : of actual proxy (for example, if a proxy runs on 192.168.X.X:8080, Android device's Wi-Fi proxy needs to target 192.168.X.X:8080).&lt;/li&gt;
&lt;li&gt;Open Perenio application on Android device.&lt;/li&gt;
&lt;li&gt;Grab the process ID (PID) of Perenio app with &lt;code&gt;uv run frida-ps -U | grep -i perenio&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Attach Frida objection to Perenio application with &lt;code&gt;uv run objection -g &quot;${pid}&quot; explore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start &lt;code&gt;android sslpinning disable&lt;/code&gt; script.&lt;/li&gt;
&lt;li&gt;On host machine, start Mitmproxy with &lt;code&gt;SSLKEYLOGFILE=/path/to/key/log/file mitmproxy --listen-port &amp;lt;PORT&amp;gt; --ssl-insecure&lt;/code&gt;. Saving SSL keys onto a file is necessary, because, even if Wireshark and Mitmproxy run concurrently, Wireshark does not log these keys itself. And without these keys, Wireshark &lt;strong&gt;&lt;em&gt;can not&lt;/em&gt;&lt;/strong&gt; decrypt the captured TLS sessions.&lt;/li&gt;
&lt;li&gt;Start Wireshark (with root privileges) and start network traffic capture (capture same network interface on which the proxy runs).&lt;/li&gt;
&lt;li&gt;Proceed to log into Perenio account.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/meetcyber/analyzing-mobile-application-http-s-traffic-using-burp-suite-and-frida-e3e91c085e91&quot;&gt;A more comprehensive guide on HTTPS proxy setup and SSL pinning bypass can be found here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The method described above, the following plain text login request was captured:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:method: POST
:scheme: https
:path: /auth/realms/aaa.kaa/protocol/openid-connect/token
:authority: oauth.perenio.com
tenantid: perenio
content-type: application/x-www-form-urlencoded
content-length: 144
accept-encoding: gzip
user-agent: okhttp/4.10.0

username=&amp;lt;email&amp;gt;&amp;amp;password=&amp;lt;account-password&amp;gt;&amp;amp;grant_type=password&amp;amp;client_id=perenio-app&amp;amp;client_secret=&amp;lt;client-secret&amp;gt;
.............:status: 200
date: Tue, 15 Sep 2026 14:59:55 GMT
content-type: application/json
vary: Accept-Encoding
cache-control: no-store
set-cookie: KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/aaa.kaa/; Secure; HttpOnly
set-cookie: KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/aaa.kaa/; Secure; HttpOnly
x-xss-protection: 1; mode=block
pragma: no-cache
x-frame-options: SAMEORIGIN
strict-transport-security: max-age=15724800; includeSubDomains
x-content-type-options: nosniff
content-encoding: gzip

{&quot;access_token&quot;:&quot;&amp;lt;access-token&amp;gt;&quot;,&quot;expires_in&quot;:864000,&quot;refresh_expires_in&quot;:51840000,&quot;refresh_token&quot;:&quot;&amp;lt;refresh-token&amp;gt;&quot;,&quot;token_type&quot;:&quot;bearer&quot;,&quot;not-before-policy&quot;:0,&quot;session_state&quot;:&quot;&amp;lt;session-state&amp;gt;&quot;,&quot;scope&quot;:&quot;profile email&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A few insights from the login request:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Login request body includes a parameter list with:&lt;ul&gt;
&lt;li&gt;Username (email).&lt;/li&gt;
&lt;li&gt;Password.&lt;/li&gt;
&lt;li&gt;Grant type = password.&lt;/li&gt;
&lt;li&gt;Client ID - client is Perenio Android application.&lt;/li&gt;
&lt;li&gt;Client secret - (seemingly) random UUID.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The access token is valid for 10 days while refresh token expires after 600 days.&lt;/li&gt;
&lt;li&gt;Session state differs with each login request (tested with a Python reimplementation of login request).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Heading back to the decompiled Perenio application, the login function is implemented in &lt;code&gt;com.perenio.data.datasource.sections.auth.AuthRepository&lt;/code&gt; function:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=15127900756113541649&quot; alt=&quot;Auth repository function&quot;&gt;&lt;/p&gt;
&lt;p&gt;With this information obtained from Wireshark packet capture, I decided to write a proof-of-concept Python script that POSTs a login request to an endpoint controlled by Perenio, receives an authorization token and queries &lt;code&gt;hxxps[://]oauth[.]perenio[.com/auth/realms/aaa[.]kaa/users/me&lt;/code&gt; endpoint to get user information of my account. The script is called &lt;a rel=&quot;nofollow&quot; href=&quot;./pythonImplementations/sampleRequest.py&quot;&gt;sampleRequest.py and can be found in pythonImplementations folder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Script also queries a third endpoint - &lt;code&gt;registrationStatus&lt;/code&gt; - to check whether an account with a given email address has been registered.&lt;/p&gt;
&lt;p&gt;Response if account exists:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &quot;status&quot;: &quot;EXISTS&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Response if account does not exist:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &quot;status&quot;: &quot;NOT_EXISTS&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; tested the rate limits on this endpoint, but it potentially could be used to enumerate existing Perenio accounts.&lt;/p&gt;
&lt;p&gt;Sample response to login request:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &quot;access_token&quot;: &quot;&amp;lt;access-token&amp;gt;&quot;,
    &quot;expires_in&quot;: 864000,
    &quot;refresh_expires_in&quot;: 51840000,
    &quot;refresh_token&quot;: &quot;&amp;lt;refresh-token&amp;gt;&quot;,
    &quot;token_type&quot;: &quot;bearer&quot;,
    &quot;not-before-policy&quot;: 0,
    &quot;session_state&quot;: &quot;&amp;lt;session-state&amp;gt;&quot;,
    &quot;scope&quot;: &quot;profile email&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sample response to user information query:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &quot;uid&quot;: &quot;&amp;lt;user-id&amp;gt;&quot;,
    &quot;countryCode&quot;: &quot;LT&quot;,
    &quot;email&quot;: &quot;&amp;lt;email&amp;gt;&quot;,
    &quot;language&quot;: &quot;EN&quot;,
    &quot;nickname&quot;: &quot;&amp;lt;nickname&amp;gt;&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also further proves that encryption methods described previously are local-only as these HTTP requests and responses contain plain text body - the encryption aspect is handed to TLSv1.3 and pinned SSL certificates.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;./pythonImplementations/sampleRequest.py&quot;&gt;The script can also be found as sampleRequest.py in pythonImplementations folder&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;analysis-of-media-stream-audio-video-&quot;&gt;Analysis of Media Stream (Audio/Video)&lt;/h2&gt;
&lt;p&gt;Perenio Peifc01 IP camera captures and transmits both audio and video streams. A sample stream was collected using &lt;code&gt;Comfast CF-922AC&lt;/code&gt; USB Wi-Fi adapter in monitor mode.&lt;/p&gt;
&lt;p&gt;Packet collection process can be described as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Figure out adapter's network interface:&lt;pre&gt;&lt;code&gt;ip a
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Figure out a wireless channel of relevant Wi-Fi network:&lt;pre&gt;&lt;code&gt;nmcli device wifi list
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Restart Comfast Wi-Fi adapter in monitor mode:&lt;pre&gt;&lt;code&gt;sudo airmon-ng start &amp;lt;comfast-interface&amp;gt; &amp;lt;channel-number&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Start Wireshark and start packet capture on &lt;code&gt;&amp;lt;comfast-interface&amp;gt;mon&lt;/code&gt; interface.&lt;/li&gt;
&lt;li&gt;Connect IP camera and smartphone to Wi-Fi (Important: connect camera and smartphone to Wi-Fi &lt;strong&gt;&lt;em&gt;after&lt;/em&gt;&lt;/strong&gt; starting packet capture - Wireshark needs to capture 4-way handshake to derive cryptographic keys for Wi-Fi network traffic decryption).&lt;/li&gt;
&lt;li&gt;Start Perenio application on Android device and access IP camera's video stream - Wireshark should capture this data as of now.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Wireshark shows heavy UDP traffic on ports &lt;code&gt;50612&lt;/code&gt;, &lt;code&gt;54386&lt;/code&gt; and &lt;code&gt;54431&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=8545383309870854821&quot; alt=&quot;Heavy UDP traffic&quot;&gt;&lt;/p&gt;
&lt;p&gt;The datagrams themselves seem to contain highly structured data - decoding them as Real-time Transport Protocol (RTP) on Wireshark with &lt;code&gt;Right click on UDP packet -&amp;gt; Decode as -&amp;gt; RTP&lt;/code&gt; reveals that the captured UDP data is audio/video stream relay between Perenio Peifc01 IP camera and a smartphone via vendor controlled Amazon AWS EC2 instance. The following structure can be inferred from this packet capture:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th align=&quot;center&quot;&gt;Port number&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Protocol&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Purpose&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;50612&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;RTP over UDP&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Audio stream &lt;code&gt;IP camera -&amp;gt; EC2 instance&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;54386&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;RTP over UDP&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Video stream &lt;code&gt;IP camera -&amp;gt; EC2 instance&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;54431&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;SRTP over UDP&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Stream relay &lt;code&gt;EC2 instance -&amp;gt; smartphone&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;IP camera sends video/audio streams as plaintext RTP data over the network to an Amazon AWS EC2 instance, controlled by the vendor. EC2 instance then relays combined audio/video stream to Android application via SRTP (Secure RTP) channel.&lt;/p&gt;
&lt;h3 id=&quot;rtp-packet-structure&quot;&gt;RTP Packet Structure&lt;/h3&gt;
&lt;p&gt;RTP header, &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/info/rfc3550/#section-5.1&quot;&gt;as per RFC3550 specification&lt;/a&gt;, has the following structure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Version (V - 2 bits):&lt;/strong&gt; identifies RTP version.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Padding (P - 1 bit):&lt;/strong&gt; if set, the packet contains one or more padding octets at the end that are not part of payload.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extension (X - 1 bit):&lt;/strong&gt; if set, fixed header must be followed by exactly one header extension.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSRC count (CC - 4 bits):&lt;/strong&gt; number of CSRC identifiers that follow fixed header.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Marker (M - 1 bit):&lt;/strong&gt; intended to allow significant events (e.g. frame boundaries) to be marked in packet stream.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload type (PT - 7 bits):&lt;/strong&gt; format of RTP payload.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sequence number (16 bits):&lt;/strong&gt; random number that increments by one for each RTP data packet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timestamp (32 bits):&lt;/strong&gt; sampling instant of the first octet in RTP data packet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Synchronization source (SSRC) identifier (32bits):&lt;/strong&gt; identifies a synchronization source that &lt;strong&gt;&lt;em&gt;should&lt;/em&gt;&lt;/strong&gt; be selected randomly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Visual RTP header representation from RFC3550 specification is presented below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=18202523034194486556&quot; alt=&quot;RTP header structure&quot;&gt;&lt;/p&gt;
&lt;p&gt;After a fixed header and CSRC identifiers (if present, RTP packet can have 0 to 15 32-bit long items as CSRC list entries right after SSRC), payload is added to the RTP packet. If padding is set to 1, a certain amount of padding bytes are appended to the packet after payload. Count of padding bytes is stored as a &lt;strong&gt;&lt;em&gt;last&lt;/em&gt;&lt;/strong&gt; byte of RTP packet (count includes this last byte as well).&lt;/p&gt;
&lt;h3 id=&quot;video-encoding&quot;&gt;Video Encoding&lt;/h3&gt;
&lt;p&gt;As a video stream codec, H.264 (also known as Advanced Video Coding - AVC) is used. When a video is encoded with a standard like H.264, the stream is sliced into Network Abstraction Layer (NAL) units for reliable data transmission over a network. However, RTP over UDP has a limit for how large a single network packet can be. This limit is called Maximum Transmission Unit (MTU) and for Ethernet/Wi-Fi networks it usually is 1500 bytes, &lt;strong&gt;&lt;em&gt;including&lt;/em&gt;&lt;/strong&gt; packet headers. Accounting for Ethernet/IPv4/UDP/RTP headers leaves 1460 bytes &lt;strong&gt;&lt;em&gt;at most&lt;/em&gt;&lt;/strong&gt; for the payload (additional header information is added to RTP packet if the packet has CSRC identifiers and/or is being sent via VPN/IPSec tunnel).&lt;/p&gt;
&lt;p&gt;Anyways, a large NAL unit can exceed single MTU, which means that such a NAL unit has to be split into multiple RTP packets for a successful transmission. For this purpose, H.264 has a defined Fragmentation Unit (FU), comprised of 1-byte FU Indicator and 1-byte FU Header.&lt;/p&gt;
&lt;h4 id=&quot;fu-indicator&quot;&gt;FU Indicator&lt;/h4&gt;
&lt;p&gt;FU Indicator is constructed against &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/info/rfc6184/#section-1.3&quot;&gt;RFC 6184 standard, section 1.3&lt;/a&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th align=&quot;center&quot;&gt;Bits&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Name&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;0&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;F&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;forbidden_zero_bit&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;1-2&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;NRI&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;nal_ref_idc&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;3-7&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Type&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;nal_unit_type&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Forbidden zero bit:&lt;/strong&gt; normally equals 0. If this bit is set to 1, it indicates that a syntax violation / bit error was detected.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NAL reference IDC (NRI):&lt;/strong&gt; when it equals 0, it means that this NAL unit is not used for reference picture reconstruction. Greater values indicate that NAL unit is required to maintain integrity of reference pictures.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NAL unit type.&lt;/strong&gt; For example, Fragmentation Unit A (FU-A) has an unit type of &lt;code&gt;28&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Visual FU Indicator structure from &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/info/rfc6184/#section-1.3&quot;&gt;RFC 6184 standard, section 1.3&lt;/a&gt; is presented below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=9202270763581905266&quot; alt=&quot;FU Indicator byte structure&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;fu-header&quot;&gt;FU Header&lt;/h4&gt;
&lt;p&gt;FU Header byte is present only on NAL Fragmentation Units and is constructed against &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/info/rfc6184/#section-5.8&quot;&gt;RFC 6184 standard, section 5.8&lt;/a&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th align=&quot;center&quot;&gt;Bits&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Name&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;0&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;S&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Start bit of fragmented NAL unit&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;1&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;E&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;End bit of fragmented NAL unit&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;2&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;R&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Reserved bit - must equal 0 and ignored by the receiver&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;3-7&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Type&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;NAL unit type&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Visual FU Header structure from &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/info/rfc6184/#section-5.8&quot;&gt;RFC 6184 standard, section 5.8&lt;/a&gt; is presented below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=7482509382101285050&quot; alt=&quot;FU Header byte structure&quot;&gt;&lt;/p&gt;
&lt;p&gt;When a NAL unit is fragmented into FU-A (and FU-B) units, the original one-byte NAL header is reconstructed by preserving the F and NRI bits from the FU indicator and taking the NAL-unit type from the FU header:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(FU Identifier &amp;amp; 0xE0) | (FU Header &amp;amp; 0x1F)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This operation swaps fragmentation unit type (28 for FU-A and 29 for FU-B) with the type of actual video data in NALU.&lt;/p&gt;
&lt;h3 id=&quot;stream-reconstruction-script&quot;&gt;Stream Reconstruction Script&lt;/h3&gt;
&lt;p&gt;Stream reconstruction script is &lt;a rel=&quot;nofollow&quot; href=&quot;./pythonImplementations/streamExtraction.py&quot;&gt;available as streamExtraction.py script in pythonImplementations folder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As of now, only the relevant features for Perenio Peifc01 IP camera's stream reconstruction are included in this script:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fragmentation Unit A (FU-A) reassembly into Network Abstraction Layer (NAL) unit.&lt;/li&gt;
&lt;li&gt;Reassembling RTP L16 (&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/info/rfc3551/#section-4.5.11&quot;&gt;as defined in RFC 3551, section 4.5.11&lt;/a&gt;) raw uncompressed audio data samples into a &lt;code&gt;.wav&lt;/code&gt; audio file.&lt;/li&gt;
&lt;li&gt;Parsing fixed header fields of RTP packet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Features that are not included in the script:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fragmentation Unit B (FU-B) reassembly into Network Abstraction Layer (NAL) unit.&lt;/li&gt;
&lt;li&gt;RTP padding removal, when it exists.&lt;/li&gt;
&lt;li&gt;Parsing (optional) CSRC fields of a RTP header.&lt;/li&gt;
&lt;li&gt;Encoding separate audio/video streams into a single media file.&lt;/li&gt;
&lt;li&gt;Audio / video synchronization and frame timing for muxing.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The script, however, produces playable audio and video files, with a reconstructed video frame presented below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=967454877087382659&quot; alt=&quot;Reconstructed video frame&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Key points to summarize the security research of Perenio application:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cryptographic method analysis of &lt;code&gt;Perenio Smart: Home and Office&lt;/code&gt; Android application revealed a few issues with how local data encryption is implemented.&lt;/li&gt;
&lt;li&gt;After successful login to Perenio account, &lt;code&gt;accessToken&lt;/code&gt; that is valid for 10 days is issued while the validity period of &lt;code&gt;refreshToken&lt;/code&gt; is 600 days.&lt;/li&gt;
&lt;li&gt;Perenio Peifc01 IP camera sends RTP packets over UDP with unencrypted audio and video streams to an Amazon AWS EC2 instance, meaning that the network traffic could be captured and audio / video data from Peifc01 IP camera be reconstructed by someone who has:&lt;ul&gt;
&lt;li&gt;Wi-Fi Pre-Shared Key (PSK) for the Wireless Local Area Network (WLAN), where Peifc01 IP camera resides.&lt;/li&gt;
&lt;li&gt;Wi-Fi adapter in monitor mode.&lt;/li&gt;
&lt;li&gt;Captures 4-way handshake as Peifc01 IP camera connects to the network.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AWS EC2 instance relays the encoded file with combined audio/video to the Perenio Android application via Secure RTP (SRTP).&lt;/li&gt;
&lt;/ol&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/28970/perenio-peifc01-ip-camera-and-android-application-analysis</guid>
<pubDate>Mon, 28 Sep 2026 20:00:58 +0000</pubDate>
</item>
<item>
<title>Signing Mesh Tokens with Vault</title>
<link>https://coderlegion.com/26026/signing-mesh-tokens-with-vault</link>
<description>&lt;p&gt;This blog is a part of the Zero-Trust Security on Istio Series, if you haven't read the previous article, please do, it will provide better context.&lt;/p&gt;
&lt;p&gt;The previous post traced one request's identity flow from gateway to database. It left one piece unexplained: how Auth Service actually signs the identity token that carries a user through the mesh. That signing step is the system's root of trust. Steal the signing key and you can forge a token for any user and any role, and every downstream service will believe it.&lt;/p&gt;
&lt;p&gt;A quick recap, so this post stands on its own. The system is an HR employee directory running on Istio. A gateway-facing service, Profile Aggregator, fans out to internal-only services like Employee Records (HR data) and Device Inventory (hardware assignments). Auth Service (&lt;code&gt;auth-service&lt;/code&gt;) sits at the gateway: it authenticates the external user and mints a short-lived signed JWT, &lt;code&gt;x-mesh-identity&lt;/code&gt; (the &quot;mesh token&quot;), that downstream service sidecars verify on every request. It signs that token with Vault, HashiCorp's secrets manager, using Vault's Transit engine, so the private key never touches application code. This post covers why that matters, how it works, and what happens when things go wrong.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-secrets-in-pods&quot;&gt;The Problem: Secrets in Pods&lt;/h3&gt;
&lt;p&gt;The default Kubernetes pattern for secrets is to mount them into pods. Environment variables, files in &lt;code&gt;/var/run/secrets&lt;/code&gt;, ConfigMaps with sensitive values. Assume any compromised pod leaks whatever secrets it holds. If your signing key is in the Auth Service environment, a container escape gives the attacker the key. They can mint tokens for any user, any role, indefinitely, from anywhere, until you detect the breach and rotate.&lt;/p&gt;
&lt;p&gt;The blast radius of a compromised pod should be limited to what that pod can do right now, not what it can do forever with stolen material.&lt;/p&gt;
&lt;h3 id=&quot;what-vault-solves-and-what-it-does-not&quot;&gt;What Vault Solves, and What It Does Not&lt;/h3&gt;
&lt;p&gt;Token signing is only one use case. In a production cluster, Vault is the central control point for secret access, audit, and rotation across the system. The larger pattern is that applications should not carry durable secret material when the platform can issue short-lived authority from workload identity.&lt;/p&gt;
&lt;p&gt;The production version removes static Vault tokens from application config. Auth Service runs under a dedicated Kubernetes service account with a projected, short-lived service-account token. Vault Kubernetes Auth maps that service account to the narrow signing policy. A Vault Agent sidecar authenticates, renews the resulting Vault token, and keeps the raw token inside the Agent boundary. Auth Service calls Vault through the Agent instead of reading a long-lived token from its own environment.&lt;/p&gt;
&lt;p&gt;There is still a credential. The difference is that it is platform-issued workload identity, not a manually provisioned Vault token sitting in app config. The remaining credential is issued by Kubernetes, rotated by the platform, scoped by Vault policy, and auditable at Vault.&lt;/p&gt;
&lt;p&gt;This POC uses the simpler version: Auth Service receives &lt;code&gt;VAULT_TOKEN&lt;/code&gt; directly. That keeps the signing flow easy to see, but it is a demo shortcut, not the endpoint of the pattern.&lt;/p&gt;
&lt;p&gt;Vault also does not make a compromised pod harmless. If the Auth Service pod is compromised, the attacker can use whatever runtime authority that pod has until you revoke or cut it off. What Vault changes is the value of that authority. Instead of stealing the RSA private key and signing offline forever, the attacker gets access to a narrow, revocable, auditable signing path. The private key stays inside Vault, every signing operation goes through a central API, and rotation is controlled in one place.&lt;/p&gt;
&lt;h3 id=&quot;vault-transit-signing-without-holding-keys&quot;&gt;Vault Transit: Signing Without Holding Keys&lt;/h3&gt;
&lt;p&gt;Vault's Transit engine is a cryptography-as-a-service API. You send it bytes, it signs them with a key it manages, and returns the signature. The key material never leaves Vault's control.&lt;/p&gt;
&lt;p&gt;In this architecture, Auth Service uses Transit for one specific operation: signing mesh identity tokens with RS256 (RSA-2048, PKCS#1 v1.5).&lt;/p&gt;
&lt;p&gt;The flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Auth Service builds the JWT header and payload (claims assembled from the authentication result).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auth Service encodes the signing input: &lt;code&gt;base64url(header).base64url(payload)&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auth Service sends those bytes to Vault: &lt;code&gt;POST /v1/transit/sign/mesh-identity&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vault signs with the current RSA private key, returns &lt;code&gt;vault:v&amp;lt;version&amp;gt;:&amp;lt;base64_signature&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auth Service strips the prefix, re-encodes as base64url, and assembles the final JWT.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/uploads/covers/6a0c37b1fd930acd9e15653e/39a6878b-4d35-4728-807c-9bbc73f6646c.png&quot; alt=&quot;Vault Transit signing: Auth Service makes two round-trips to Vault to fetch the key version and sign; the RSA private key never leaves Vault, and the final JWT is assembled from the returned signature&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def sign_payload(payload_bytes: bytes) -&amp;gt; str:
    &quot;&quot;&quot;Signs a payload using Vault Transit and returns the raw signature&quot;&quot;&quot;
    url = f&quot;{settings.VAULT_URL}/v1/transit/sign/mesh-identity&quot;
    headers = {&quot;X-Vault-Token&quot;: settings.VAULT_TOKEN}

    encoded_payload = base64.b64encode(payload_bytes).decode(&quot;utf-8&quot;)
    data = {
        &quot;input&quot;: encoded_payload,
        &quot;hash_algorithm&quot;: &quot;sha2-256&quot;,
        &quot;signature_algorithm&quot;: &quot;pkcs1v15&quot;,
    }

    response = _client.post(url, headers=headers, json=data)
    response.raise_for_status()
    result = response.json()

    # Vault returns the signature as &quot;vault:v&amp;lt;version&amp;gt;:&amp;lt;base64sig&amp;gt;&quot;; strip the prefix for JWS.
    sig = result[&quot;data&quot;][&quot;signature&quot;]
    parts = sig.split(&quot;:&quot;)
    if len(parts) &amp;gt;= 3:
        return parts[2]
    return sig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two Vault round-trips happen per token mint: one to fetch the current key version (for the &lt;code&gt;kid&lt;/code&gt; header claim), one to sign. In this POC, Auth Service mints a fresh mesh token for every protected gateway request. That keeps the behavior simple and security-first: every request gets a new &lt;code&gt;iat&lt;/code&gt;, &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;jti&lt;/code&gt;, and signing decision, and key rotation is observed immediately.&lt;/p&gt;
&lt;p&gt;The tradeoff is that Vault sits in the synchronous request path. Under production load, you may choose to cache mesh tokens inside Auth Service until their 5-minute expiry, keyed by session, subject, roles, audience, and delegation context. The token still stays inside the platform boundary: it is not returned to the browser, stored in a user cookie, or exposed to frontend code. Caching removes most signing calls for repeated requests from the same user flow.&lt;/p&gt;
&lt;p&gt;The cost is freshness: revocation, role changes, and key rotation take effect at token-expiry boundaries instead of per request.&lt;/p&gt;
&lt;p&gt;Caching also constrains the token shape. Keep request-specific data such as &lt;code&gt;x-request-id&lt;/code&gt; outside the token so the same mesh assertion can safely travel with multiple requests. That would require changing the current POC token, because this implementation includes &lt;code&gt;request_id&lt;/code&gt; in the JWT payload.&lt;/p&gt;
&lt;h3 id=&quot;the-jwks-endpoint-public-key-distribution&quot;&gt;The JWKS Endpoint: Public Key Distribution&lt;/h3&gt;
&lt;p&gt;Every service sidecar needs to verify mesh tokens. Auth Service exposes &lt;code&gt;GET /auth/jwks&lt;/code&gt;, which fetches all active public key versions from Vault and formats them as a standard RFC 7517 JWKS response:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def get_jwks() -&amp;gt; dict:
    &quot;&quot;&quot;Format Vault public keys as JWKS&quot;&quot;&quot;
    keys = vault_client.get_public_keys()
    jwks = {&quot;keys&quot;: []}
    for version, key_info in keys.items():
        public_key = serialization.load_pem_public_key(key_info[&quot;public_key&quot;].encode(&quot;utf-8&quot;))
        if isinstance(public_key, RSAPublicKey):
            numbers = public_key.public_numbers()
            jwks[&quot;keys&quot;].append({
                &quot;kty&quot;: &quot;RSA&quot;,
                &quot;kid&quot;: str(version),
                &quot;use&quot;: &quot;sig&quot;,
                &quot;alg&quot;: &quot;RS256&quot;,
                &quot;n&quot;: int_to_base64url(numbers.n),
                &quot;e&quot;: int_to_base64url(numbers.e),
            })
    return jwks
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There's no version filtering in this code, and none is needed. &lt;code&gt;get_public_keys()&lt;/code&gt; reads the &lt;code&gt;keys&lt;/code&gt; map from &lt;code&gt;vault read transit/keys/mesh-identity&lt;/code&gt;, and Vault only returns the &lt;em&gt;working set&lt;/em&gt; there: versions from &lt;code&gt;min_decryption_version&lt;/code&gt; through the latest. Anything below &lt;code&gt;min_decryption_version&lt;/code&gt; is archived and dropped from that response, so it never reaches the JWKS output. The filtering happens inside Vault, not in application code. That makes &lt;code&gt;min_decryption_version&lt;/code&gt; the single switch controlling which keys sidecars will accept, and it's why rotation and invalidation are two separate operations, covered next.&lt;/p&gt;
&lt;p&gt;This cluster runs istiod with &lt;code&gt;PILOT_JWT_ENABLE_REMOTE_JWKS&lt;/code&gt; enabled, so each Envoy sidecar fetches this endpoint directly over mTLS, rather than istiod fetching it once and pushing the keys. A sidecar caches the response and refreshes on its own schedule, on the order of 5 minutes. During rotation, there's a window where a sidecar still holds the old key set. More on that below.&lt;/p&gt;
&lt;h3 id=&quot;key-rotation&quot;&gt;Key Rotation&lt;/h3&gt;
&lt;p&gt;Rotation happens in two steps: create a new key version, then invalidate old versions.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
# Step 1: Rotate — creates a new key version, old versions remain valid
vault write -f transit/keys/mesh-identity/rotate

# Step 2: Invalidate — bumps min_decryption_version so old keys can't verify
vault write transit/keys/mesh-identity/config \
  min_decryption_version=$NEW_LATEST
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;--grace&lt;/code&gt; flag in the rotation script introduces a 300-second (5-minute) wait between these steps. Why 5 minutes? Because mesh tokens have a 5-minute TTL. After one full TTL passes, all tokens signed with the old key have expired. No valid old-key tokens remain in flight, so invalidating the old key causes no disruption.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [ &quot;$1&quot; = &quot;--grace&quot; ]; then
    echo &quot;Grace period: waiting 300s for in-flight tokens to expire...&quot;
    sleep 300
fi
vault write transit/keys/mesh-identity/config \
    min_decryption_version=$NEW_LATEST
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bumping &lt;code&gt;min_decryption_version&lt;/code&gt; removes the old version from the JWKS endpoint, but sidecars don't pick that up instantly. Each one validates tokens against the JWKS it last fetched. A failed validation does not trigger an immediate refetch. The sidecar keeps using that cached key set until its next scheduled refresh, on the order of the 5-minute cache interval above.&lt;/p&gt;
&lt;p&gt;That cache lag is exactly why the grace period exists. By waiting one full 5-minute token TTL before bumping the minimum, every token signed with the old key has already expired. After that, it no longer matters whether a given sidecar has refreshed its JWKS. If it still has the old public key cached, there are no valid old-key tokens left to accept. If it has refreshed, it only sees the new key. Skip the grace period and you risk rejecting still-valid old-key tokens the moment a sidecar refreshes mid-flight. Either way, bumping the minimum only &lt;em&gt;archives&lt;/em&gt; a version; it stays recoverable by lowering &lt;code&gt;min_decryption_version&lt;/code&gt; again, and is gone for good only once it drops below &lt;code&gt;min_available_version&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The grace period covers the old key. The new key has a separate window. Auth Service sets &lt;code&gt;kid&lt;/code&gt; to the latest version on every mint, so it starts issuing tokens signed with the new key the instant you rotate. A sidecar whose JWKS cache is still stale has no public key for that &lt;code&gt;kid&lt;/code&gt; yet, and rejects those freshly-minted tokens with a 403. So rotation should also trigger a JWKS cache invalidation, forcing every sidecar to refetch immediately and pick up the new public key before any new-key token reaches it. That closes the window so clients never see a 403.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/uploads/covers/6a0c37b1fd930acd9e15653e/3c0ce24c-7d12-4457-ada1-fd9c2a8e852c.png&quot; alt=&quot;Key rotation timeline with two tracks: the old key drains safely across the 5-minute grace window before min_decryption_version is bumped, while newly minted new-key tokens can be rejected with 403 until sidecars refetch JWKS&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;vault-token-scoping&quot;&gt;Vault Token Scoping&lt;/h3&gt;
&lt;p&gt;In this POC, Auth Service holds a Vault token with exactly two capabilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;update&lt;/code&gt; on &lt;code&gt;transit/sign/mesh-identity&lt;/code&gt; (can sign)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;read&lt;/code&gt; on &lt;code&gt;transit/keys/mesh-identity&lt;/code&gt; (can read public keys and current version)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It cannot rotate keys, cannot modify key configuration, cannot access any other Vault path. This is the minimum privilege needed for signing and JWKS serving.&lt;/p&gt;
&lt;p&gt;The token has a 32-day renewable period. Rotation of the Vault token itself (revoking and reissuing) is a separate operational concern from key rotation. In the production model described earlier, this same policy would be attached to the Vault token issued through Kubernetes Auth and managed by Vault Agent.&lt;/p&gt;
&lt;h3 id=&quot;blast-radius-what-happens-when-things-break&quot;&gt;Blast Radius: What Happens When Things Break&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Auth Service compromised:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The attacker has the pod's signing authority: the direct Vault token in this POC, or access to the Agent-mediated signing path in the production model. They can sign arbitrary payloads under &lt;code&gt;mesh-identity&lt;/code&gt; and read public keys. They can mint tokens for any user, any role, with any audience. That breaks the user-identity layer for any service that accepts &lt;code&gt;x-mesh-identity&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It does not automatically bypass every mesh policy. Downstream &lt;code&gt;AuthorizationPolicy&lt;/code&gt; rules still check the caller's mTLS workload identity, and the token still has to carry the expected &lt;code&gt;aud&lt;/code&gt; (audience: which services may accept the token) and &lt;code&gt;act&lt;/code&gt; (the delegation claim naming the authorized intermediary) claims for that route. A forged token from the wrong pod can still fail the source-principal check. The real danger is that the compromised Auth Service can mint tokens that look legitimate to the JWT layer, including tokens with audiences and delegation claims chosen by the attacker.&lt;/p&gt;
&lt;p&gt;But the damage is bounded. The attacker cannot rotate keys or modify Vault configuration. You revoke the direct Vault token, or revoke the Agent-issued token and cut off the Kubernetes Auth path for that workload, and their signing ability stops. In-flight tokens they've already minted expire within 5 minutes. You rotate the key and bump &lt;code&gt;min_decryption_version&lt;/code&gt;, which drops the compromised version from the JWKS endpoint so sidecars stop accepting anything signed with it once they refresh their cache.&lt;/p&gt;
&lt;p&gt;Detection: Vault audit logs show every signing request with the token accessor. Anomalous patterns (sudden spike in signing, unusual audiences) are detectable if audit logging is enabled.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vault compromised:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the worst case, but the severity depends on the compromise depth. If the attacker gains root token access or breaks into the Vault API, they can sign arbitrary tokens through Transit. There's still an audit trail (Vault audit log records each API call), and you recover by rotating the Transit key and revoking the compromised token.&lt;/p&gt;
&lt;p&gt;If the attacker extracts the actual key material (storage backend compromise, memory dump, unsealed Vault snapshot), they can sign tokens offline, from anywhere, without making Vault API calls. No audit trail. Tokens they produce are indistinguishable from legitimate ones until you rotate to an entirely new key.&lt;/p&gt;
&lt;p&gt;In this POC, Vault uses &lt;code&gt;emptyDir&lt;/code&gt; storage (data lives only in the pod's ephemeral filesystem). In production, Vault would use encrypted backend storage with auto-unseal via a cloud KMS. The private key's residency model depends entirely on how Vault is deployed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A downstream service compromised (Employee Records, Device Inventory, etc.):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The attacker can read projected headers for any request that arrives at that service. They see user IDs and roles for requests they handle. They cannot mint new mesh tokens (no Vault access) and cannot call other internal-only (Tier 2) services (AuthorizationPolicy blocks it).&lt;/p&gt;
&lt;p&gt;For database access, the compromised service has its scoped DB role (Employee Records can access &lt;code&gt;hr.*&lt;/code&gt; tables, Device Inventory can access &lt;code&gt;it.*&lt;/code&gt;). A malicious process could call &lt;code&gt;set_config('app.current_user_id', ...)&lt;/code&gt; with an arbitrary value to bypass row-level security (RLS) within its own schema. RLS stops application bugs, not a fully malicious process controlling its own DB session. The containment here is schema isolation (Employee Records can't query &lt;code&gt;it.*&lt;/code&gt; tables) and AuthorizationPolicy (Employee Records can't reach Device Inventory's database path).&lt;/p&gt;
&lt;h3 id=&quot;the-anti-patterns&quot;&gt;The Anti-Patterns&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Local key pairs:&lt;/strong&gt; Auth Service generates and holds an RSA key pair. Compromise means the attacker has the key forever (until you detect and rotate). No audit trail of signing operations. No centralized rotation procedure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shared HMAC secrets:&lt;/strong&gt; All services share a symmetric key for signing/verification. Any compromised service can mint tokens. The blast radius of a single pod compromise becomes total. Rotation requires coordinated rollout to every service simultaneously.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Secrets in environment variables:&lt;/strong&gt; The key material is readable by any process in the container (via &lt;code&gt;/proc/self/environ&lt;/code&gt;), visible in crash dumps, and exposed through the container runtime debug surface. Even &lt;code&gt;secretKeyRef&lt;/code&gt; values end up as plaintext in the process environment once the pod starts. This is the Kubernetes default for &quot;sensitive config.&quot;&lt;/p&gt;
&lt;p&gt;Each of these works fine at small scale with a trusted team. They become unacceptable when the question shifts from &quot;can someone on our team see this secret&quot; to &quot;what happens when one pod in a 50-service mesh is compromised.&quot;&lt;/p&gt;
&lt;h3 id=&quot;what-s-next&quot;&gt;What's Next&lt;/h3&gt;
&lt;p&gt;The next post covers authorization in depth: how network-level, request-level, resource-level, and field-level authorization compose into a system where each layer catches what the one above it misses.&lt;/p&gt;
&lt;h3 id=&quot;code&quot;&gt;Code&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Kaustav-Sarkar/Istio-Defense-In-Depth&quot;&gt;https://github.com/Kaustav-Sarkar/Istio-Defense-In-Depth&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/26026/signing-mesh-tokens-with-vault</guid>
<pubDate>Wed, 02 Sep 2026 02:07:34 +0000</pubDate>
</item>
<item>
<title>EU's Controversial Chat Control Amendment Passed and Potential Security Implications</title>
<link>https://coderlegion.com/22437/eus-controversial-chat-control-amendment-passed-and-potential-security-implications</link>
<description>&lt;p&gt;On July 3rd, 2026, a controversial amendment was passed to an already controversial legislation described by many as a normalization of mass surveillance and undermining legitimate users' privacy online. In this article, we will dive deeper into the security implications for messaging service platforms.&lt;/p&gt;
&lt;h4 id=&quot;scanning-user-messages&quot;&gt;Scanning User Messages&lt;/h4&gt;
&lt;p&gt;As per the new amendment that was passed, platforms will be able to voluntarily scan user messages that are not encrypted end-to-end for any material involving child sexual abuse. This means messaging platforms like those on mainstream social media will be able to run scans over private messages between users, including photos, texts, and maybe even videos, to detect any potentially illegal material.&lt;/p&gt;
&lt;p&gt;In practice, messaging platforms now have a legal basis to read private messages between users and hide behind the new amendment.&lt;/p&gt;
&lt;h4 id=&quot;how-&quot;&gt;How?&lt;/h4&gt;
&lt;p&gt;The big question is more technical rather than legal. However, the implications can be severe for both users and platforms, especially if platforms don't have a properly structured solution.&lt;/p&gt;
&lt;p&gt;The most obvious solution that comes to mind is that they could create a cadence for running all the stored messages to be scanned by an LLM solution and configure alerts for any content that could raise red flags to be reviewed by the platform and potentially reported and delivered to the corresponding authorities either through a legal team or a dedicated platform. I'm not aware at the moment of any platforms that are made for such a purpose, but I'm speculating how this could work in practice.&lt;/p&gt;
&lt;p&gt;If private user messages are encrypted at rest, this means there will also be a considerable computing cost for platforms to decrypt the content during the scanning periods.&lt;/p&gt;
&lt;p&gt;If we take Telegram as an example, Telegram claims that they deliver 15 billion messages per day as of July 13, 2026. We do not know how many of those messages belong to their secret chat feature, so let's assume that the majority of the messages are not encrypted end-to-end.&lt;/p&gt;
&lt;h4 id=&quot;technical-risks&quot;&gt;Technical Risks&lt;/h4&gt;
&lt;p&gt;If we assume that platforms will rely on LLM-based solutions, we have to discuss the risks.&lt;/p&gt;
&lt;h5 id=&quot;ai-false-positives-and-bias&quot;&gt;AI False Positives and Bias&lt;/h5&gt;
&lt;p&gt;LLMs do make mistakes. This is why NIST AI RMF as well as OWASP Top 10 AI Security and Governance standards require human-in-the-loop for sensitive decisions. While human-in-the-loop is considered a best practice for sensitive decisions, bringing AI into the mix also brings with it all the common risks, including overconfidence, LLM bias, and drift.&lt;/p&gt;
&lt;p&gt;Just running an AI scan doesn't mean that it will always properly classify the content. AI would be great for existing content but not for new content if AI isn't trained for it.&lt;/p&gt;
&lt;h5 id=&quot;scanning-tools&quot;&gt;Scanning Tools&lt;/h5&gt;
&lt;p&gt;Effective scanning solutions are usually vendor-provided and bring with them their own risks, since any mistake on the vendor's side could expose all users' private data and even cause a data breach. Scanning tools that use LLM integrations require exposing the decrypted users' private messages to an external party. If not handled securely on both ends of the process (platform and vendor), the risk and potential of data breaches increases further.&lt;/p&gt;
&lt;h5 id=&quot;average-users-think-messages-are-private&quot;&gt;Average Users Think Messages Are Private&lt;/h5&gt;
&lt;p&gt;Let's be honest. The majority of platform users aren't technical. I have personally encountered countless people who use private messages to store secrets such as credit card numbers, passwords, and other personal and sensitive content.&lt;/p&gt;
&lt;p&gt;Platforms have no way to prevent users from using private messages in that capacity, and this is why platforms do not have the incentive to scan users' messages in the first place, as this would arguably impact their profits as well as expose them to legal liabilities.&lt;/p&gt;
&lt;h4 id=&quot;alternative-solutions&quot;&gt;Alternative Solutions&lt;/h4&gt;
&lt;p&gt;One way in which platforms could perform a scan without compromising users' privacy (at least before an alert is triggered) is to instead perform hash-based comparisons.&lt;/p&gt;
&lt;p&gt;If platforms have specific files or texts to monitor for, they could compare the hashes instead of the decrypted content.&lt;/p&gt;
&lt;h4 id=&quot;there-is-no-perfect-solution&quot;&gt;There Is No Perfect Solution&lt;/h4&gt;
&lt;p&gt;Even if we deploy hash-based detection instead of scanning users' private messages, the compute cost would be huge because not only do some platforms have to keep content encrypted at rest but also run hashing algorithm comparisons to detect the content in question if it exists.&lt;/p&gt;
&lt;p&gt;Hashing also can be useful only for common or known content. So hashing wouldn't be that useful to spot modified content.&lt;/p&gt;
&lt;p&gt;AI could do slightly better in terms of spotting patterns. However, this takes us again into the issues and risks mentioned earlier.&lt;/p&gt;
&lt;h4 id=&quot;environmental-impact&quot;&gt;Environmental Impact&lt;/h4&gt;
&lt;p&gt;The sheer volume of messages exchanged daily globally between users is already stressing data centers that are trying to expand their capacity to accommodate both regular companies' needs as well as AI.&lt;/p&gt;
&lt;p&gt;The carbon footprint of scanning users' private messages at scale will only increase the burden on an already heating planet.&lt;/p&gt;
&lt;h4 id=&quot;ethical-considerations&quot;&gt;Ethical Considerations&lt;/h4&gt;
&lt;p&gt;Relying on AI LLMs to flag users could have severe consequences on human rights if someone is flagged or accused of something illegal by mistake or by error. Even with human-in-the-loop, human biases could also lead to discrimination and bias based on the user's legally protected traits such as language, nationality, or religion.&lt;/p&gt;
&lt;p&gt;The fact that human intervention might be needed (platform's forensic or security teams) to manually review flagged content and potentially users' private conversations raises serious implications for users' privacy. Just because an AI flagged a certain user's messages doesn't mean that they are automatically guilty.&lt;/p&gt;
&lt;p&gt;In edge cases, users might accidentally share content that may seem, at surface, like a meme and end up in criminal prosecution. The accusation alone could have severe implications on a person's life in terms of society, their own family, and more.&lt;/p&gt;
&lt;h4 id=&quot;alternative-solutions-1&quot;&gt;Alternative Solutions&lt;/h4&gt;
&lt;p&gt;In my opinion, all children deserve protection. Violation of privacy of individuals or groups online is not protection in the pure sense. A more effective strategy to combat child abuse is by grassroots movements, awareness campaigns, and better legislation that addresses structural problems such as inequality and domestic violence.&lt;/p&gt;
&lt;h4 id=&quot;useful-sources&quot;&gt;Useful Sources&lt;/h4&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://oeil.europarl.europa.eu/oeil/en/document-summary?id=1891790&quot;&gt;https://oeil.europarl.europa.eu/oeil/en/document-summary?id=1891790&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://telegram.org/blog/100-million&quot;&gt;https://telegram.org/blog/100-million&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/22437/eus-controversial-chat-control-amendment-passed-and-potential-security-implications</guid>
<pubDate>Mon, 13 Jul 2026 05:56:00 +0000</pubDate>
</item>
<item>
<title>How We Added E2E Encryption on Top of a Local-First Architecture</title>
<link>https://coderlegion.com/18562/how-we-added-e2e-encryption-on-top-of-a-local-first-architecture</link>
<description>&lt;p&gt;I used to track my finances in an app. Salary, loans, small transfers, all of it. At some point I got curious whether the team behind it could actually see those numbers in their database. So I wrote them and asked. They never replied.&lt;/p&gt;
&lt;p&gt;That stuck with me. When we started building Finsight, I did not want our users in that same spot, wondering what happens to their data on someone else's server. So privacy went into the architecture from day one, not added later, not bolted on before launch.&lt;/p&gt;
&lt;p&gt;The goal was simple: data should be inaccessible not because the team promises to behave, but because technically the team cannot read it even if they wanted to.&lt;/p&gt;
&lt;h3 id=&quot;https-is-not-end-to-end&quot;&gt;HTTPS Is Not End-to-End&lt;/h3&gt;
&lt;p&gt;HTTPS protects the connection between the phone and the server. That is necessary, but it only covers the wire. Once the request lands on the server, the data sits there in plain text. If a transaction amount of 530 arrives, the server sees 530, period.&lt;/p&gt;
&lt;p&gt;Encrypting the database on the server does not help either. It protects against stolen disks and leaked backups, but while the server is running it decrypts data on the fly and reads it like anything else. Inside the application layer it is still plaintext.&lt;/p&gt;
&lt;p&gt;So at some point the server sees balances, notes, and amounts anyway. We wanted to eliminate that moment entirely.&lt;/p&gt;
&lt;h3 id=&quot;where-we-drew-the-line&quot;&gt;Where We Drew the Line&lt;/h3&gt;
&lt;p&gt;In a &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/doszhan/why-your-app-feels-slow-and-how-we-fixed-it-with-powersync-ehc&quot;&gt;previous&lt;/a&gt; article we covered the move to local-first. The short version: every user has their own SQLite database on their device. The UI reads and writes directly to it, so everything opens instantly and works offline. PowerSync runs in the background and keeps the local database in sync with the server.&lt;/p&gt;
&lt;p&gt;That solved the performance problem. But it raised another one: data travels constantly between the device and the server, and anyone along that path could potentially read it.&lt;/p&gt;
&lt;p&gt;Our answer was to encrypt sensitive fields directly on the device before PowerSync sends anything. What reaches the server is already scrambled. Only a client holding the key can decrypt it. The server never sees the key.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;input  --&amp;gt; plaintext into local SQLite
       --&amp;gt; encryption on the client
       --&amp;gt; ciphertext into the sync table
       --&amp;gt; PowerSync carries ciphertext to the server
       --&amp;gt; another device receives ciphertext
       --&amp;gt; client decrypts locally
       --&amp;gt; UI reads normal plaintext again
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For PowerSync these are just rows. It does not need to understand what is inside them.&lt;/p&gt;
&lt;h3 id=&quot;two-tables-instead-of-one&quot;&gt;Two Tables Instead of One&lt;/h3&gt;
&lt;p&gt;If we encrypt data before sending it, the UI has a problem: it needs the values in readable form. You cannot render a transaction list from scrambled strings, and a monthly expense filter would not work on them either.&lt;/p&gt;
&lt;p&gt;So for every sensitive entity we maintain two tables.&lt;/p&gt;
&lt;p&gt;One is local, with plain values, and the UI reads from it. In PowerSync these tables are marked as &lt;code&gt;localOnly&lt;/code&gt; and never leave the device. The second is the sync table, with the same records but sensitive fields already encrypted. PowerSync moves this one between the device and the server.&lt;/p&gt;
&lt;p&gt;For an account the schema looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// Local table with plain values, never leaves the device
export const accounts = new Table(
  {
    organization_id: column.text,
    name: column.text,    // plaintext
    balance: column.real, // regular number
    currency_id: column.text,
    // ...
  },
  { localOnly: true }
);

// Sync table with the same fields, but name and balance hold ciphertext
export const accountsEncrypt = new Table({
  organization_id: column.text,
  name: column.text,    // encrypted
  balance: column.text, // text instead of real because it holds ciphertext
  currency_id: column.text,
  // ...
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same pair exists for every sensitive entity:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;accounts        --&amp;gt; accounts_encrypt
transactions    --&amp;gt; transactions_encrypt
debts           --&amp;gt; debts_encrypt
loans           --&amp;gt; loans_encrypt
loan_payments   --&amp;gt; loan_payments_encrypt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We do not encrypt entire rows, only specific fields: amounts, balances, notes, lender names, interest rates. Things like dates, user and organization IDs, and relations between records stay visible. Without them the server cannot route rows to the right devices.&lt;/p&gt;
&lt;p&gt;That is a tradeoff, and there is more on it below.&lt;/p&gt;
&lt;h3 id=&quot;how-it-works-in-code&quot;&gt;How It Works in Code&lt;/h3&gt;
&lt;p&gt;When a user creates an account, the UI writes a row to the plain &lt;code&gt;accounts&lt;/code&gt; table. No encryption yet, no sync. Just a normal insert into the local database.&lt;/p&gt;
&lt;p&gt;The database itself is a &lt;code&gt;PowerSyncDatabase&lt;/code&gt; instance. On initialization it gets a schema with all the tables and a filename where SQLite will store the data on the device:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { PowerSyncDatabase } from '@powersync/web';

const db = new PowerSyncDatabase({
  database: { dbFilename: 'finsight.db' },
  schema: AppSchema, // all tables, both local-only and sync
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From there it gets interesting. PowerSync can subscribe to changes and notify which tables just changed. We use that as a trigger to run the crypto layer:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// Fires every time one of the tables changes
db.onChange({
  onChange: async ({ changedTables }) =&amp;gt; {
    for (const table of changedTables) {
      await handleTableChange(table);
    }
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;handleTableChange&lt;/code&gt; function is a simple router. It looks at the table name and decides which direction to go: encrypt freshly written data before it gets sent, or decrypt incoming data from the server so the UI can display it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;async function handleTableChange(table) {
  // User changed something locally, encrypt and write to the sync copy
  if (table === 'accounts')     return encryptAccounts();
  if (table === 'transactions') return encryptTransactions();

  // Encrypted row arrived from the server, decrypt for the UI
  if (table === 'accounts_encrypt')     return decryptAccounts();
  if (table === 'transactions_encrypt') return decryptTransactions();

  // ...debts, loans, payments follow the same pattern
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both directions are needed. The first makes sure data gets encrypted before PowerSync picks it up. The second makes sure anything that arrived from another device gets turned back into readable numbers and strings so the UI can show it right away.&lt;/p&gt;
&lt;p&gt;After that, PowerSync looks only at the encrypted tables and sends accumulated changes to the server in batches. On the backend they map to regular Django models. The &lt;code&gt;Transaction.amount&lt;/code&gt; field is declared as &lt;code&gt;TextField&lt;/code&gt; rather than a number because it holds ciphertext. The server stores the string, returns it on request, and cannot read what is inside.&lt;/p&gt;
&lt;h3 id=&quot;keys&quot;&gt;Keys&lt;/h3&gt;
&lt;p&gt;Everything depends on a key the server does not know. If the server had it, e2e would be pointless.&lt;/p&gt;
&lt;p&gt;We use a two-layer scheme. Each organization has a main key called the DEK (data encryption key). It is what actually encrypts the financial fields. The DEK is a random sequence of bytes that no one types or memorizes.&lt;/p&gt;
&lt;p&gt;The DEK itself is also encrypted, wrapped by another key called the KEK (key encryption key). The KEK is derived from the user's secret key, a passphrase they set specifically for data encryption and separate from their account password. The derivation uses Argon2id from libsodium, an algorithm designed to make passphrase brute-forcing computationally expensive.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;secret key + salt  --&amp;gt;  KEK
random DEK         --&amp;gt;  encrypted DEK (wrapped by KEK)
DEK                --&amp;gt;  encrypted financial fields
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The server stores only the encrypted DEK and its metadata. It never sees the raw DEK, the KEK, or the secret key.&lt;/p&gt;
&lt;p&gt;The upside is that changing the secret key is cheap. Instead of re-encrypting every transaction and account, we just unwrap the DEK with the old KEK and re-wrap it with a new one derived from the new key. The DEK stays the same, so all the encrypted data stays untouched.&lt;/p&gt;
&lt;p&gt;The downside is that without the secret key and without a backup, the data is gone. The server has no plaintext copy to recover from. No support ticket fixes this, because the server genuinely does not have the key.&lt;/p&gt;
&lt;h3 id=&quot;what-gets-harder&quot;&gt;What Gets Harder&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;encrypt()&lt;/code&gt; call itself takes three lines. The complexity lives around it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validation.&lt;/strong&gt; Before e2e, most business rules ran on the server. An amount came in, the server checked it against the balance and the constraints. Now the server sees a string like &lt;code&gt;eyJhbGciOiJBMjU2R0NN...&lt;/code&gt; and cannot say anything meaningful about it. Some checks moved to the client. The server still handles access control, relational integrity, quotas, and structure, but it can no longer verify what is actually inside an encrypted field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debugging.&lt;/strong&gt; When a user reports a discrepancy, it used to take two minutes to look up the row in PostgreSQL. Now those fields are base64 strings unreadable without the user's key. Reproducing the issue means working on the client: inspecting local SQLite, checking the upload queue, looking at sync state. The server database stopped being the place where you look for answers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Logging.&lt;/strong&gt; The server should never see plaintext. But the client sees it constantly, before encryption and after decryption. Client logging has to be designed deliberately so a routine log line does not accidentally capture an amount or a note.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Device load on first sync.&lt;/strong&gt; When a user signs into a fresh device, the full history has to come down and every single row needs to be decrypted locally. The server cannot help with that part. Early on we hit real bugs from this: rows arriving in batches, decryption running in parallel, race conditions and UI stalls while everything was still catching up.&lt;/p&gt;
&lt;h3 id=&quot;what-the-server-still-sees&quot;&gt;What the Server Still Sees&lt;/h3&gt;
&lt;p&gt;With e2e the server does not see nothing. It sees a lot of metadata, and that is worth saying plainly.&lt;/p&gt;
&lt;p&gt;The server knows who the user is and which organization they belong to, the IDs of every record, the fact that transactions and accounts and debts exist, their dates and types, relations between records, creation and update timestamps, and the size of each encrypted value.&lt;/p&gt;
&lt;p&gt;Metadata alone can say quite a bit. The server may not know the transaction amount, but it can see that health-related transactions tripled this month. Or that a new currency appeared in the account list.&lt;/p&gt;
&lt;p&gt;So I do not call e2e full invisibility. The heaviest financial values — amounts, balances, rates, and notes — do not reach the server in plain form. But the shape of the data, who has what and when, is visible to the server. That is the actual line we drew, nothing more.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;E2e in production is not a weekend project. It shifts how you think about the backend, the client, validation, and debugging. The backend knows less. The client takes on more responsibility.&lt;/p&gt;
&lt;p&gt;If your product does not handle sensitive data, this complexity is probably not worth it. But when a finance app holds a real piece of someone's life, it becomes clear why you would build it this way. That is what we did in &lt;a rel=&quot;nofollow&quot; href=&quot;https://zentline.com/en/finsight/&quot;&gt;Finsight&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18562/how-we-added-e2e-encryption-on-top-of-a-local-first-architecture</guid>
<pubDate>Thu, 21 May 2026 11:48:34 +0000</pubDate>
</item>
<item>
<title>The Complete Roadmap to Master Cryptography From Beginner to Expert</title>
<link>https://coderlegion.com/6766/the-complete-roadmap-to-master-cryptography-from-beginner-to-expert</link>
<description>&lt;p&gt;Admit it: we usually do not think about cryptography until something fails. But there stand behind every online transaction, private communication medical record, and national secret the unseen, silent protectors working to keep everything safe. That protector is cryptography the uncelebrated guardian of the digital age.&lt;/p&gt;
&lt;p&gt;Now, as artificial intelligence gets sharper and quantum computers edge closer to reality, that protection is being put to the ultimate test. Data breaches are practically daily news, and cybercriminals aren’t just getting smarter they’re getting faster and stronger.&lt;/p&gt;
&lt;p&gt;But here’s the bright side: the world needs skilled cryptographers more than ever. Demand is exploding, and if you’re curious, driven, this field offers incredible opportunities.&lt;/p&gt;
&lt;p&gt;Whether you're starting from scratch or you're a programmer or any technical fields, this roadmap will take you from the basics of encryption all the way through to advanced cryptographic systems. Are you ready? Let's begin.&lt;/p&gt;
&lt;h3 id=&quot;step-1-lay-the-math-groundwork&quot;&gt;Step 1: Lay the Math Groundwork&lt;/h3&gt;
&lt;p&gt;You don't need to be a mathematical wizard, but you should have a solid grasp of several topics. Think of this as putting together your cryptography toolbox.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What to focus on:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Number Theory: Primes, modular arithmetic, greatest common divisors&lt;br&gt;
these aren't something a mathematician learned in a textbook. They're&lt;br&gt;
the building blocks of RSA and most other cryptographic algorithms.&lt;/li&gt;
&lt;li&gt;Discrete Math: Logic, combinatorics, and graph theory are the&lt;br&gt;
foundation of secure protocols. &lt;/li&gt;
&lt;li&gt;Linear Algebra: Necessary particularly for understanding how encryption is performed especially&lt;br&gt;
in post-quantum vector- and matrix-based systems. &lt;/li&gt;
&lt;li&gt;Probability &amp;amp; Statistics: These will be useful when assessing how secure an&lt;br&gt;
encryption method actually is and whether its security reasoning&lt;br&gt;
holds up.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you're an autodidact, sites like Khan Academy and Coursera have excellent, introductory courses to get you started.&lt;/p&gt;
&lt;h3 id=&quot;step-2-familiarize-yourself-with-core-concepts&quot;&gt;Step 2: Familiarize Yourself with Core Concepts&lt;/h3&gt;
&lt;p&gt;Now that your math foundation is in place, it's time to jump into the fundamentals of modern crypto.&lt;/p&gt;
&lt;p&gt;Encryption &amp;amp; Decryption&lt;br&gt;
Cryptography essentially involves making readable information (plaintext) unreadable code (ciphertext)and vice versa exclusive to individuals who have the proper key. Think of locking a diary: only the individual holding the key can access what's inside.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Symmetric vs. Asymmetric Encryption&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Symmetric: One key required quick, efficient, great with bulk data.AES (Advanced Encryption Standard) reigns supreme here, used by everyone from governments to banks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asymmetric: Two keys a public key for locking and a private key for unlocking.This means strangers can securely communicate without ever having to exchange a secret beforehand. RSA and Elliptic Curve Cryptography (ECC) dominate.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Hashing &amp;amp; Data Integrity&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A hash function takes in any input and spits out a predetermined length &quot;fingerprint.&quot; Alter just one letter, and the hash is totally different. That is why hashes are perfect for verifying files or storing passwords safely. SHA-256? That is the hash used by Bitcoin and digital signatures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Digital Certificates &amp;amp; Signatures&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;These ensure a message or file wasn't tampered with and using which, that it ever again came from the author who said it did. Certificates from reputable authorities (CAs) are what make your browser show you that tiny padlock when you're visiting a secure site.&lt;/p&gt;
&lt;h3 id=&quot;step-3-get-into-classical-crypto&quot;&gt;Step 3: Get into Classical Crypto&lt;/h3&gt;
&lt;p&gt;Even before computers, human beings still needed secrets. Ancient ciphers appear simple today, but they teach us timeless lessons about how codes work and get cracked.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caesar Cipher&lt;/strong&gt;: Shift each letter by a fixed number. Used by great Julius Caesar , Simple to crack now, but it introduces the idea of keys and algorithms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vigenère Cipher&lt;/strong&gt;: Use a keyword to vary the shift, making it far harder to crack. It fooled humans for centuries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Substitution Ciphers&lt;/strong&gt;: Swap letters around. Billions of combinations—but frequency analysis (like spotting that “E” is the most common letter in English) can unravel them.&lt;/p&gt;
&lt;p&gt;Studying these isn’t just history—it’s training in cryptanalysis, the art of breaking codes. And to build strong systems, you’ve got to understand how they fail.&lt;/p&gt;
&lt;h3 id=&quot;step-4-tackle-modern-cryptography&quot;&gt;Step 4: Tackle Modern Cryptography&lt;/h3&gt;
&lt;p&gt;Recent crypto relies on simple math problems to figure out in one direction but nearly impossible to figure out the reverse without a legitimate key.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AES: The go-to symmetric algorithm. Encrypts your Wi-Fi and personal&lt;br&gt;
files. Learn about block modes, key sizes (128, 192, 256 bits), and&lt;br&gt;
how it's so highly relied upon.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RSA: Because large prime numbers are hard to factor. Slower than AES but essential for key exchange and digital signatures. Typically 2048 bits or larger keys.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ECC (Elliptic Curve Cryptography): Offers the same security as RSA with much, much shorter keys (256-bit ECC = 2048-bit RSA). Ideal for phones and IOT.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Diffie-Hellman: The secret behind secure communications—HTTPS, VPNs,etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SHA-3: The latest in secure hashing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-5-consider-how-it-works-in-the-real-world&quot;&gt;Step 5: Consider How It Works in the Real World&lt;/h3&gt;
&lt;p&gt;Learning algorithms is one thing. Learning how they're put into practice in actual systems is quite another.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SSL/TLS &amp;amp; HTTPS: That lock icon in your browser? That's TLS using&lt;br&gt;
asymmetric crypto to set up a link, then falling back to symmetric&lt;br&gt;
for speed.&lt;/li&gt;
&lt;li&gt;PGP (Pretty Good Privacy): The gold standard for encrypted email and&lt;br&gt;
file signing—employed by journalists and privacy activists.&lt;/li&gt;
&lt;li&gt;VPNs: Establish encrypted tunnels with protocols like IPsec,&lt;br&gt;
concealing your traffic from unwanted onlookers.&lt;/li&gt;
&lt;li&gt;Blockchain: Built from scratch with crypto—hashes for mining, digital&lt;br&gt;
signatures for transactions. Bitcoin and Ethereum couldn't exist&lt;br&gt;
without it.&lt;/li&gt;
&lt;li&gt;Homomorphic Encryption: Early days, but revolutionary. Enabling you&lt;br&gt;
to compute on encrypted data without decrypting it perfect for&lt;br&gt;
private AI or secure cloud processing.(still not practically)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-6-get-your-hands-dirty&quot;&gt;Step 6: Get Your Hands Dirty&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Theory is great, but only until you actually do it. Real learning happens when you create, destroy, and recreate.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CryptoHack: Enjoyable, game-ified exercises where you implement and&lt;br&gt;
attack real crypto systems in a sandbox.&lt;/li&gt;
&lt;li&gt;Cryptopals: Code-intensive exercises that force you to construct (and&lt;br&gt;
destroy) ciphers from scratch. Harsh—but genius. Tools to Know:&lt;/li&gt;
&lt;li&gt;PyCryptodome (Python): Perfect for prototyping encryption.&lt;/li&gt;
&lt;li&gt;OpenSSL: The Swiss Army knife for keys, certs, and command-line&lt;br&gt;
crypto.&lt;/li&gt;
&lt;li&gt;Build Projects: Try a password manager, a mini blockchain, or an&lt;br&gt;
encrypted chat app. Nothing cements knowledge like shipping something&lt;br&gt;
real.&lt;/li&gt;
&lt;li&gt;Contribute to Open Source: Jump into projects like OpenSSL or&lt;br&gt;
libsodium. Code reviews from seasoned cryptographers are worth more&lt;br&gt;
than any course.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-7-level-up-with-advanced-topics&quot;&gt;Step 7: Level Up with Advanced Topics&lt;/h3&gt;
&lt;p&gt;Once you’ve got the fundamentals down, the real frontier opens up.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Post-Quantum Cryptography: RSA and ECC will be compromised by quantum&lt;br&gt;
computers. The answer? New math problems even quantum machines can't crack easily. NIST already standardized two: CRYSTALS-Kyber (for encryption) and CRYSTALS-Dilithium (for signatures) both lattices.&lt;/li&gt;
&lt;li&gt;Cryptanalysis: Master attacking like an attacker. Master&lt;br&gt;
differential/linear cryptanalysis, timing attacks, side-channel&lt;br&gt;
leakage. Defense starts with an understanding of offense.&lt;/li&gt;
&lt;li&gt;Zero-Knowledge Proofs: Prove you have something—without revealing&lt;br&gt;
what. Deployed in Zcash and Ethereum's zk-rollups, this is privacy&lt;br&gt;
tech at its best.&lt;/li&gt;
&lt;li&gt;Lattice-Based Crypto: Not only quantum-resistant but also enables&lt;br&gt;
fully homomorphic encryption. Complex, perhaps but much stronger.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-8-certifications-amp-career-paths&quot;&gt;Step 8: Certifications &amp;amp; Career Paths&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CompTIA Security+: Nice intro to security fundamentals, including&lt;br&gt;
crypto fundamentals.&lt;/li&gt;
&lt;li&gt;CISSP: Industry gold standard for infosec professionals—covers crypto&lt;br&gt;
in depth.&lt;/li&gt;
&lt;li&gt;ECES (Certified Encryption Specialist): Extremely crypto-centric in&lt;br&gt;
terms of crypto design and implementation.&lt;/li&gt;
&lt;li&gt;OSCP: Hands-on, offensive security cert that stresses actual skill&lt;br&gt;
over memorization.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Where You Can Go:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cryptographic Software Engineer: Create secure systems from the&lt;br&gt;
ground up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Blockchain Security Architect: Create crypto protocols for&lt;br&gt;
decentralized applications.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post-Quantum Researcher: Future-proof encryption against quantum&lt;br&gt;
attacks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pen Tester / Security Specialist: Seek out vulnerabilities with&lt;br&gt;
sophisticated crypto knowledge.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Government &amp;amp; Defense: Organizations like the NSA hire top&lt;br&gt;
cryptographers for high-security operations. Final Thoughts&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You don't learn cryptography in a weekend. It's a journey of persistent studying, testing, and yes, a lot of failure. But the payoff? Huge. You'll work on interesting problems, earn decent money, and get to make a real difference in protecting people's data in a more and more exposed digital world.&lt;/p&gt;
&lt;p&gt;Start with the basics. Move step by step. Don’t fear failure every expert cryptographer learned by breaking things first.&lt;/p&gt;
&lt;p&gt;And remember: the best time to start learning cryptography was yesterday.&lt;br&gt;
The second-best time? Right now.&lt;/p&gt;
</description>
<category>Cybersecurity</category>
<guid isPermaLink="true">https://coderlegion.com/6766/the-complete-roadmap-to-master-cryptography-from-beginner-to-expert</guid>
<pubDate>Thu, 23 Oct 2025 12:40:49 +0000</pubDate>
</item>
<item>
<title>Oracle Autonomous Database Security: Maintenance, Access Control, and Encryption</title>
<link>https://coderlegion.com/6178/oracle-autonomous-database-security-maintenance-access-control-and-encryption</link>
<description>&lt;p&gt;Oracle Autonomous Database implements comprehensive security measures spanning automated maintenance, network access control, and end-to-end encryption. Understanding these integrated security capabilities is essential for organizations deploying mission-critical applications in autonomous database environments.&lt;/p&gt;
&lt;h3 id=&quot;automated-maintenance-and-patching&quot;&gt;&lt;strong&gt;Automated Maintenance and Patching&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;oracle-managed-patching-process&quot;&gt;&lt;strong&gt;Oracle-Managed Patching Process&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Scheduled Maintenance Operations:&lt;/strong&gt;&lt;br&gt;
Autonomous Database uses predefined maintenance windows to automatically patch your database, ensuring security updates and feature enhancements are applied consistently without manual intervention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Oracle's Patching Responsibility:&lt;/strong&gt;&lt;br&gt;
Oracle patches the database during the scheduled maintenance period, handling all aspects of the update process including validation, deployment, and verification.&lt;/p&gt;
&lt;h4 id=&quot;continuous-database-availability&quot;&gt;&lt;strong&gt;Continuous Database Availability&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Zero-Downtime Maintenance:&lt;/strong&gt;&lt;br&gt;
The database remains available throughout the maintenance project, ensuring business continuity during patching operations through rolling update mechanisms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maintenance Window Duration:&lt;/strong&gt;&lt;br&gt;
The maintenance window is no more than 2 hours, providing predictable timeframes for update operations while minimizing any potential impact.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Serverless Patching Model:&lt;/strong&gt;&lt;br&gt;
Users cannot modify the patch schedule in Autonomous Database Serverless, as Oracle fully manages the maintenance timing to ensure optimal update coordination across the platform.&lt;/p&gt;
&lt;h4 id=&quot;transparent-application-continuity-tac-&quot;&gt;&lt;strong&gt;Transparent Application Continuity (TAC)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Session State Protection:&lt;/strong&gt;&lt;br&gt;
TAC is transparent, completely safe, and requires no thinking—it protects all session states during maintenance operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Protected Session Elements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sequences:&lt;/strong&gt; Sequence values preserved across maintenance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Temporary Tables:&lt;/strong&gt; Temp table contents maintained&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session Roles:&lt;/strong&gt; Role assignments and privileges retained&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session Variables:&lt;/strong&gt; PL/SQL variables and application context preserved&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transaction State:&lt;/strong&gt; In-flight transactions handled gracefully&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Application Benefits:&lt;/strong&gt;&lt;br&gt;
Applications continue operating without awareness of underlying maintenance activities, eliminating the need for application-level retry logic or connection management during updates.&lt;/p&gt;
&lt;h3 id=&quot;network-access-control&quot;&gt;&lt;strong&gt;Network Access Control&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;access-control-lists-acls-&quot;&gt;&lt;strong&gt;Access Control Lists (ACLs)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;ACL Overview:&lt;/strong&gt;&lt;br&gt;
ACLs provide a mechanism to block all IP addresses that are not in a specified list for accessing a database, implementing IP-based network security controls.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Access Control Behavior:&lt;/strong&gt;&lt;br&gt;
Once an ACL is set up, the database will only accept connections from addresses in the ACL, and all other connections will be rejected, providing explicit allow-list security.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ACL Configuration Flexibility:&lt;/strong&gt;&lt;br&gt;
ACLs can be configured for an Autonomous Database at any time—during initial provisioning or for existing databases—providing flexible security policy implementation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Supported ACL Formats:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Individual IP Addresses:&lt;/strong&gt; Specific host IP addresses (e.g., 203.0.113.5)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CIDR Block Ranges:&lt;/strong&gt; Classless Inter-Domain Routing notation for IP ranges (e.g., 10.0.0.0/24)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Virtual Cloud Networks (VCNs):&lt;/strong&gt; Entire VCN CIDR blocks for cloud-native access control&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;acl-use-cases-and-best-practices&quot;&gt;&lt;strong&gt;ACL Use Cases and Best Practices&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Corporate Network Access:&lt;/strong&gt;&lt;br&gt;
Restrict database access to corporate IP ranges or VPN endpoints:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Corporate Office: 203.0.113.0/24
VPN Gateway: 198.51.100.10
Development VCN: 10.0.0.0/16
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Geographic Restrictions:&lt;/strong&gt;&lt;br&gt;
Limit access to specific geographic regions for compliance requirements or security policies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Third-Party Integration:&lt;/strong&gt;&lt;br&gt;
Allow specific partner or vendor IP addresses for B2B integrations while blocking general internet access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ACL Management:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Regular review and update of ACL entries&lt;/li&gt;
&lt;li&gt;Documentation of all allowed IP addresses and purposes&lt;/li&gt;
&lt;li&gt;Removal of obsolete entries to maintain security hygiene&lt;/li&gt;
&lt;li&gt;Testing of ACL changes in non-production environments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;private-endpoints-for-enhanced-security&quot;&gt;&lt;strong&gt;Private Endpoints for Enhanced Security&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;private-endpoint-architecture&quot;&gt;&lt;strong&gt;Private Endpoint Architecture&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Complete Internet Isolation:&lt;/strong&gt;&lt;br&gt;
You can specify that an Autonomous Database uses a private endpoint inside your Virtual Cloud Network (VCN) in your tenancy to keep all traffic to and from your database off the public internet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Private Endpoint Configuration:&lt;/strong&gt;&lt;br&gt;
You can configure a private endpoint when you provision or clone an Autonomous Database, or you can switch to using a private endpoint in an existing database.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Network Isolation Benefits:&lt;/strong&gt;&lt;br&gt;
Private endpoints provide the ability to NOT permit any public access to your database, ensuring complete network isolation within your cloud infrastructure.&lt;/p&gt;
&lt;h4 id=&quot;private-endpoint-implementation&quot;&gt;&lt;strong&gt;Private Endpoint Implementation&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;VCN Integration:&lt;/strong&gt;&lt;br&gt;
Configure a VCN in your tenancy to use with the private endpoint, creating a secure private network boundary for database access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Private IP Address:&lt;/strong&gt;&lt;br&gt;
The database receives a private IP address within your VCN, accessible only from resources within the same VCN or connected networks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Secure Connectivity Options:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Same VCN:&lt;/strong&gt; Direct access from compute instances in the same VCN&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VCN Peering:&lt;/strong&gt; Access from peered VCNs in the same or different regions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VPN Connections:&lt;/strong&gt; Secure on-premises access through site-to-site VPN&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FastConnect:&lt;/strong&gt; Dedicated private connectivity from on-premises networks&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;private-endpoint-vs-acl-comparison&quot;&gt;&lt;strong&gt;Private Endpoint vs. ACL Comparison&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;When to Use Private Endpoints:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complete elimination of public internet exposure required&lt;/li&gt;
&lt;li&gt;Integration with existing VCN architecture&lt;/li&gt;
&lt;li&gt;Compliance requirements mandate private networking&lt;/li&gt;
&lt;li&gt;High-security applications with strict network isolation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When to Use ACLs:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Public endpoint access with IP restrictions sufficient&lt;/li&gt;
&lt;li&gt;External partners need database access&lt;/li&gt;
&lt;li&gt;Simpler network architecture preferred&lt;/li&gt;
&lt;li&gt;Mobile or distributed user base requires flexibility&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Combined Approach:&lt;/strong&gt;&lt;br&gt;
Private endpoints and ACLs serve different purposes—private endpoints eliminate public access entirely, while ACLs restrict which public IPs can connect when using public endpoints.&lt;/p&gt;
&lt;h4 id=&quot;important-security-considerations&quot;&gt;&lt;strong&gt;Important Security Considerations&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;ACL and Private Endpoint Interaction:&lt;/strong&gt;&lt;br&gt;
If you had ACLs defined for the public endpoint, the ACLs do not apply for the private endpoint—private endpoints use VCN security lists and network security groups instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;URL Changes:&lt;/strong&gt;&lt;br&gt;
After you update the network access to use a private endpoint, the URL for Database Tools is different compared to using a public endpoint, requiring application configuration updates.&lt;/p&gt;
&lt;h3 id=&quot;data-encryption-and-key-management&quot;&gt;&lt;strong&gt;Data Encryption and Key Management&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;transparent-data-encryption-tde-&quot;&gt;&lt;strong&gt;Transparent Data Encryption (TDE)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;At-Rest Encryption:&lt;/strong&gt;&lt;br&gt;
Transparent Data Encryption (TDE) enables you to encrypt data you store in tables and tablespaces, providing automatic encryption without application changes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TDE Benefits:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transparent Operation:&lt;/strong&gt; Applications require no modifications&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Comprehensive Protection:&lt;/strong&gt; Encrypts data files, redo logs, and backups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance Optimized:&lt;/strong&gt; Hardware-accelerated encryption with minimal overhead&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compliance Ready:&lt;/strong&gt; Meets regulatory encryption requirements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Encryption Scope:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tablespace Encryption:&lt;/strong&gt; Entire tablespaces encrypted automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Column Encryption:&lt;/strong&gt; Specific sensitive columns encrypted selectively&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backup Encryption:&lt;/strong&gt; Database backups encrypted by default&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data File Encryption:&lt;/strong&gt; Physical data files protected at storage level&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;network-encryption&quot;&gt;&lt;strong&gt;Network Encryption&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;TLS 1.2 Protocol:&lt;/strong&gt;&lt;br&gt;
Oracle Autonomous Database implements TLS 1.2 for secure network communications, ensuring industry-standard encryption for data in transit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Native Network Encryption:&lt;/strong&gt;&lt;br&gt;
Oracle's native network encryption (NNE) provides additional encryption capabilities for database connections, complementing TLS for comprehensive network security.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encryption Protocols:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TLS 1.2:&lt;/strong&gt; Modern, secure transport layer security&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mutual TLS (mTLS):&lt;/strong&gt; Bidirectional certificate-based authentication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strong Cipher Suites:&lt;/strong&gt; AES-256 and other robust encryption algorithms&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perfect Forward Secrecy:&lt;/strong&gt; Protection against future key compromises&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;key-management-architecture&quot;&gt;&lt;strong&gt;Key Management Architecture&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;HSM-Based Key Management:&lt;/strong&gt;&lt;br&gt;
Oracle Cloud Infrastructure provides HSM-based Key Management Service (KMS) for secure encryption key storage and lifecycle management.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KMS Features:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hardware Security Modules:&lt;/strong&gt; FIPS 140-2 Level 3 certified HSMs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Centralized Key Management:&lt;/strong&gt; Unified key management across services&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key Rotation:&lt;/strong&gt; Automated or manual key rotation capabilities&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Audit Logging:&lt;/strong&gt; Comprehensive key usage audit trails&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Customer-Controlled Key Management:&lt;/strong&gt;&lt;br&gt;
Customers control key generation and rotation, maintaining sovereignty over encryption keys and meeting strict compliance requirements.&lt;/p&gt;
&lt;h4 id=&quot;exadata-cloud-customer-key-management&quot;&gt;&lt;strong&gt;Exadata Cloud@Customer Key Management&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Oracle Key Vault Integration:&lt;/strong&gt;&lt;br&gt;
Integration with on-premises Oracle Key Vault for Autonomous Database on Exadata Cloud@Customer (ADB-ExaC@C) enables hybrid key management strategies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hybrid Key Management Benefits:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;On-Premises Control:&lt;/strong&gt; Keys remain in customer data centers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Centralized Management:&lt;/strong&gt; Unified key management across cloud and on-premises&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compliance Alignment:&lt;/strong&gt; Meet data residency and sovereignty requirements&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disaster Recovery:&lt;/strong&gt; Key backup and recovery capabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;end-to-end-data-protection&quot;&gt;&lt;strong&gt;End-to-End Data Protection&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Comprehensive Encryption Strategy:&lt;/strong&gt;&lt;br&gt;
Data is encrypted both at rest and in transit, providing complete protection throughout the data lifecycle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encryption Layers:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Application Layer:&lt;/strong&gt; Optional application-level encryption&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database Layer:&lt;/strong&gt; TDE for at-rest encryption&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network Layer:&lt;/strong&gt; TLS for data in motion&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage Layer:&lt;/strong&gt; Storage-level encryption for additional protection&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Defense in Depth:&lt;/strong&gt;&lt;br&gt;
Multiple encryption layers ensure data remains protected even if one layer is compromised, implementing security best practices for enterprise data protection.&lt;/p&gt;
&lt;h3 id=&quot;security-monitoring-and-compliance&quot;&gt;&lt;strong&gt;Security Monitoring and Compliance&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;audit-and-compliance-capabilities&quot;&gt;&lt;strong&gt;Audit and Compliance Capabilities&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Unified Auditing:&lt;/strong&gt;&lt;br&gt;
Comprehensive audit logging captures all database activities, security events, and administrative operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Security Monitoring:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Access Attempts:&lt;/strong&gt; Logging successful and failed authentication attempts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privilege Usage:&lt;/strong&gt; Tracking privileged operations and administrative actions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Access:&lt;/strong&gt; Monitoring sensitive data access patterns&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration Changes:&lt;/strong&gt; Recording security policy modifications&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;compliance-certifications&quot;&gt;&lt;strong&gt;Compliance Certifications&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Industry Standards:&lt;/strong&gt;&lt;br&gt;
Oracle Autonomous Database maintains compliance with major regulatory frameworks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SOC 1, 2, 3:&lt;/strong&gt; Service Organization Control reports&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ISO 27001, 27017, 27018:&lt;/strong&gt; International security standards&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PCI DSS:&lt;/strong&gt; Payment Card Industry Data Security Standard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HIPAA:&lt;/strong&gt; Health Insurance Portability and Accountability Act&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FedRAMP:&lt;/strong&gt; Federal Risk and Authorization Management Program&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GDPR:&lt;/strong&gt; General Data Protection Regulation compliance&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;security-best-practices&quot;&gt;&lt;strong&gt;Security Best Practices&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;network-security-best-practices&quot;&gt;&lt;strong&gt;Network Security Best Practices&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Defense-in-Depth Approach:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement private endpoints for maximum isolation&lt;/li&gt;
&lt;li&gt;Use ACLs when public access is required&lt;/li&gt;
&lt;li&gt;Configure VCN security lists and NSGs appropriately&lt;/li&gt;
&lt;li&gt;Regular review and audit of network access policies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Zero Trust Architecture:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify every access request regardless of source&lt;/li&gt;
&lt;li&gt;Implement least-privilege access principles&lt;/li&gt;
&lt;li&gt;Use strong authentication mechanisms&lt;/li&gt;
&lt;li&gt;Monitor and log all access attempts&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;encryption-best-practices&quot;&gt;&lt;strong&gt;Encryption Best Practices&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Key Management:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rotate encryption keys regularly per security policies&lt;/li&gt;
&lt;li&gt;Document key management procedures&lt;/li&gt;
&lt;li&gt;Test key recovery processes&lt;/li&gt;
&lt;li&gt;Maintain separation of duties for key operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Comprehensive Encryption:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable TDE for all sensitive data&lt;/li&gt;
&lt;li&gt;Use strong cipher suites for network encryption&lt;/li&gt;
&lt;li&gt;Implement mutual TLS where appropriate&lt;/li&gt;
&lt;li&gt;Regular security assessments and penetration testing&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;operational-security&quot;&gt;&lt;strong&gt;Operational Security&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Maintenance Planning:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Review maintenance schedules and customize when possible&lt;/li&gt;
&lt;li&gt;Test applications with TAC to verify continuity&lt;/li&gt;
&lt;li&gt;Monitor maintenance operations and validate success&lt;/li&gt;
&lt;li&gt;Document maintenance procedures and policies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Access Control:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement principle of least privilege&lt;/li&gt;
&lt;li&gt;Regular access reviews and audits&lt;/li&gt;
&lt;li&gt;Use groups and roles for consistent permissions&lt;/li&gt;
&lt;li&gt;Document all access grants and justifications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;advanced-security-scenarios&quot;&gt;&lt;strong&gt;Advanced Security Scenarios&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;multi-tier-security-architecture&quot;&gt;&lt;strong&gt;Multi-Tier Security Architecture&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Application Tier Security:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Application-level authentication and authorization&lt;/li&gt;
&lt;li&gt;Web application firewalls (WAF) for HTTP/HTTPS traffic&lt;/li&gt;
&lt;li&gt;API gateway security and rate limiting&lt;/li&gt;
&lt;li&gt;DDoS protection at edge layer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Network Tier Security:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Private endpoints for database isolation&lt;/li&gt;
&lt;li&gt;VCN security lists for network segmentation&lt;/li&gt;
&lt;li&gt;Network security groups for fine-grained control&lt;/li&gt;
&lt;li&gt;Traffic inspection and monitoring&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Database Tier Security:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TDE for data-at-rest encryption&lt;/li&gt;
&lt;li&gt;Database-level access control and auditing&lt;/li&gt;
&lt;li&gt;Database Vault for privileged user restrictions&lt;/li&gt;
&lt;li&gt;Real-time security monitoring and alerting&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;hybrid-and-multi-cloud-security&quot;&gt;&lt;strong&gt;Hybrid and Multi-Cloud Security&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Consistent Security Policies:&lt;/strong&gt;&lt;br&gt;
Maintain consistent security posture across cloud and on-premises environments through:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unified key management with Oracle Key Vault&lt;/li&gt;
&lt;li&gt;Centralized audit log aggregation and analysis&lt;/li&gt;
&lt;li&gt;Consistent network security policies&lt;/li&gt;
&lt;li&gt;Standardized encryption and access controls&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;devsecops-integration&quot;&gt;&lt;strong&gt;DevSecOps Integration&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Security Automation:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automated security testing in CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Infrastructure-as-code security scanning&lt;/li&gt;
&lt;li&gt;Automated compliance validation&lt;/li&gt;
&lt;li&gt;Continuous security monitoring and response&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;troubleshooting-and-common-issues&quot;&gt;&lt;strong&gt;Troubleshooting and Common Issues&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&quot;acl-configuration-issues&quot;&gt;&lt;strong&gt;ACL Configuration Issues&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Common Problems:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Overly restrictive ACLs blocking legitimate access&lt;/li&gt;
&lt;li&gt;CIDR block calculation errors&lt;/li&gt;
&lt;li&gt;Missing VCN entries for cloud resources&lt;/li&gt;
&lt;li&gt;ACL changes not immediately effective&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Resolution Steps:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify ACL entries include all required IP ranges&lt;/li&gt;
&lt;li&gt;Use CIDR calculators for network range validation&lt;/li&gt;
&lt;li&gt;Test connectivity from multiple sources&lt;/li&gt;
&lt;li&gt;Allow time for ACL propagation&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;private-endpoint-connectivity&quot;&gt;&lt;strong&gt;Private Endpoint Connectivity&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Common Challenges:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VCN routing configuration issues&lt;/li&gt;
&lt;li&gt;Security list or NSG restrictions&lt;/li&gt;
&lt;li&gt;DNS resolution problems&lt;/li&gt;
&lt;li&gt;VPN or FastConnect connectivity issues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Troubleshooting Approach:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify VCN routing tables and gateways&lt;/li&gt;
&lt;li&gt;Check security lists and NSG rules&lt;/li&gt;
&lt;li&gt;Test DNS resolution from source networks&lt;/li&gt;
&lt;li&gt;Validate VPN or FastConnect configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Oracle Autonomous Database provides comprehensive security through automated maintenance with Transparent Application Continuity, flexible network access control via ACLs and private endpoints, and end-to-end encryption for data protection. These integrated security capabilities enable organizations to maintain robust security postures while benefiting from autonomous database automation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Security Capabilities:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Automated Maintenance:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zero-downtime patching during 2-hour windows&lt;/li&gt;
&lt;li&gt;Transparent Application Continuity protecting session state&lt;/li&gt;
&lt;li&gt;Oracle-managed security updates without user intervention&lt;/li&gt;
&lt;li&gt;Predictable maintenance schedules with minimal impact&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Network Access Control:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ACLs for IP-based access restrictions&lt;/li&gt;
&lt;li&gt;Private endpoints for complete internet isolation&lt;/li&gt;
&lt;li&gt;Flexible configuration during provisioning or post-deployment&lt;/li&gt;
&lt;li&gt;Integration with VCN security architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Comprehensive Encryption:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TDE for data-at-rest protection&lt;/li&gt;
&lt;li&gt;TLS 1.2 for data-in-transit security&lt;/li&gt;
&lt;li&gt;Customer-controlled key management&lt;/li&gt;
&lt;li&gt;HSM-based key storage and protection&lt;/li&gt;
&lt;li&gt;End-to-end data protection throughout lifecycle&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Strategic Security Benefits:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduced Complexity:&lt;/strong&gt; Automated security operations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Protection:&lt;/strong&gt; Multiple security layers and controls&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compliance Ready:&lt;/strong&gt; Industry-standard certifications&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operational Excellence:&lt;/strong&gt; Simplified security management&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By implementing these security capabilities, organizations can confidently deploy mission-critical applications on Oracle Autonomous Database knowing that comprehensive protection is built into the platform, from automated patching and maintenance through network isolation to encryption and key management.&lt;/p&gt;
</description>
<category>Database</category>
<guid isPermaLink="true">https://coderlegion.com/6178/oracle-autonomous-database-security-maintenance-access-control-and-encryption</guid>
<pubDate>Wed, 08 Oct 2025 08:54:17 +0000</pubDate>
</item>
<item>
<title>Understanding Encryption: Data Privacy &amp; Security</title>
<link>https://coderlegion.com/3173/understanding-encryption-data-privacy-security</link>
<description>&lt;h5 id=&quot;introduction&quot;&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;In today’s digital age, information is the currency that powers governments, businesses, and individuals alike. As vast amounts of data travel across networks and are stored on servers around the globe, the risk of data breaches, surveillance, and unauthorized access has increased exponentially. To address these risks, encryption serves as the cornerstone of modern cybersecurity. It ensures that even if data falls into the wrong hands, it remains unreadable without the proper credentials. This essay explores the principles of encryption, its various forms, real-world applications, challenges, and future prospects.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;what-is-encryption-&quot;&gt;&lt;strong&gt;What is Encryption?&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Encryption is a method of converting readable data, known as plaintext, into an unreadable format, called ciphertext. Only those with the correct decryption key can revert the ciphertext back to plaintext. This transformation ensures that data remains confidential and secure from unauthorized access.&lt;/p&gt;
&lt;p&gt;The concept is ancient, with historical roots in the &lt;strong&gt;Caesar Cipher&lt;/strong&gt; and other substitution methods. However, modern encryption is a product of sophisticated mathematical algorithms and is integral to cybersecurity infrastructures across the globe.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;why-is-encryption-important-&quot;&gt;&lt;strong&gt;Why is Encryption Important?&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Encryption plays a pivotal role in maintaining:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Confidentiality&lt;/strong&gt;: Only authorized parties can access information.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integrity&lt;/strong&gt;: Ensures that the information has not been altered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authentication&lt;/strong&gt;: Validates the origin of the data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non-repudiation&lt;/strong&gt;: Proves that a message was indeed sent by the sender and cannot be denied later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Without encryption, any data transferred over the internet, such as credit card numbers, medical records, or personal messages, would be vulnerable to interception and misuse.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;types-of-encryption&quot;&gt;&lt;strong&gt;Types of Encryption&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Encryption methods can be broadly classified into two categories:&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;1-symmetric-key-encryption&quot;&gt;&lt;strong&gt;1. Symmetric Key Encryption&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;This is the simplest form of encryption where &lt;strong&gt;one key&lt;/strong&gt; is used for both encryption and decryption. Both the sender and receiver must share this secret key securely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Examples of symmetric encryption algorithms&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AES (Advanced Encryption Standard)&lt;/strong&gt; – widely used in government and financial sectors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DES (Data Encryption Standard)&lt;/strong&gt; – now largely deprecated.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blowfish and Twofish&lt;/strong&gt; – alternatives with varying complexity and security levels.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast and efficient.&lt;/li&gt;
&lt;li&gt;Suitable for encrypting large volumes of data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Key distribution is a major challenge. If the key is intercepted during transmission, the encryption can be compromised.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;2-asymmetric-key-encryption&quot;&gt;&lt;strong&gt;2. Asymmetric Key Encryption&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Also known as &lt;strong&gt;public key cryptography&lt;/strong&gt;, this method uses a pair of keys:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Public Key&lt;/strong&gt;: Available to everyone and used to encrypt data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Private Key&lt;/strong&gt;: Known only to the recipient and used to decrypt data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Popular asymmetric algorithms&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RSA (Rivest-Shamir-Adleman)&lt;/strong&gt; – one of the earliest and most widely used.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elliptic Curve Cryptography (ECC)&lt;/strong&gt; – offers similar security with smaller key sizes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diffie-Hellman&lt;/strong&gt; – used primarily for key exchange.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No need to share a private key.&lt;/li&gt;
&lt;li&gt;Enhances secure communication and digital signatures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slower than symmetric encryption.&lt;/li&gt;
&lt;li&gt;Computationally intensive, making it less ideal for encrypting large data sets.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;3-hash-functions&quot;&gt;&lt;strong&gt;3. Hash Functions&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Although not encryption in the traditional sense, &lt;strong&gt;hashing&lt;/strong&gt; is a cryptographic technique used to ensure data integrity. A hash function converts data into a fixed-size string (digest), which changes drastically with even the slightest modification in input.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SHA-256&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MD5&lt;/strong&gt; (deprecated due to vulnerabilities)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hashes are commonly used in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Password storage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Digital signatures&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File integrity checks&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h5 id=&quot;encryption-in-real-world-applications&quot;&gt;&lt;strong&gt;Encryption in Real-World Applications&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Encryption is deeply embedded in our digital lives, often working in the background without our awareness.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;1-messaging-and-communication&quot;&gt;&lt;strong&gt;1. Messaging and Communication&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Apps like &lt;strong&gt;WhatsApp&lt;/strong&gt;, &lt;strong&gt;Signal&lt;/strong&gt;, and &lt;strong&gt;Telegram&lt;/strong&gt; use &lt;strong&gt;end-to-end encryption (E2EE)&lt;/strong&gt; to ensure that only the sender and recipient can read the messages. Even the platform provider cannot access the content.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;2-e-commerce-and-online-banking&quot;&gt;&lt;strong&gt;2. E-Commerce and Online Banking&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Websites that begin with &lt;strong&gt;HTTPS&lt;/strong&gt; are using &lt;strong&gt;TLS/SSL&lt;/strong&gt; encryption to secure data transmission between the user’s browser and the website server. This protects payment information, login credentials, and other sensitive data.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;3-data-storage-and-cloud-security&quot;&gt;&lt;strong&gt;3. Data Storage and Cloud Security&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Cloud providers such as &lt;strong&gt;Amazon Web Services (AWS)&lt;/strong&gt;, &lt;strong&gt;Google Cloud&lt;/strong&gt;, and &lt;strong&gt;Microsoft Azure&lt;/strong&gt; offer encryption for data at rest and in transit. This ensures protection against data breaches and compliance with global regulations like &lt;strong&gt;GDPR&lt;/strong&gt; and &lt;strong&gt;HIPAA&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;4-emails-and-file-sharing&quot;&gt;&lt;strong&gt;4. Emails and File Sharing&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Encrypted email services like &lt;strong&gt;ProtonMail&lt;/strong&gt; and tools like &lt;strong&gt;PGP (Pretty Good Privacy)&lt;/strong&gt; provide secure communication for individuals and businesses. File-sharing platforms also incorporate encryption to protect data during upload/download.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;5-digital-signatures-and-blockchain&quot;&gt;&lt;strong&gt;5. Digital Signatures and Blockchain&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Encryption underpins &lt;strong&gt;digital signatures&lt;/strong&gt;, which ensure message authenticity and integrity. In &lt;strong&gt;blockchain&lt;/strong&gt; technologies, encryption maintains the immutability and trustworthiness of distributed ledgers.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;challenges-of-encryption&quot;&gt;&lt;strong&gt;Challenges of Encryption&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;While encryption is indispensable, it does come with challenges:&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;1-key-management&quot;&gt;&lt;strong&gt;1. Key Management&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;One of the biggest hurdles is managing encryption keys. Poor key storage or unauthorized access to keys can undermine the entire encryption system.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;2-performance-overhead&quot;&gt;&lt;strong&gt;2. Performance Overhead&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Encrypting and decrypting data, especially with asymmetric encryption, requires significant computational resources. This can impact performance, particularly in high-traffic systems.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;3-legal-and-regulatory-issues&quot;&gt;&lt;strong&gt;3. Legal and Regulatory Issues&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Some governments argue that encryption hinders law enforcement by creating &lt;strong&gt;&quot;warrant-proof&quot;&lt;/strong&gt; communication channels. This has led to debates over &lt;strong&gt;backdoors&lt;/strong&gt; in encryption systems, which experts warn could be exploited by malicious actors.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;4-compatibility-and-usability&quot;&gt;&lt;strong&gt;4. Compatibility and Usability&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Encryption systems must be seamlessly integrated with existing applications without degrading user experience. Poor implementation can lead to security flaws.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;5-obsolescence-of-algorithms&quot;&gt;&lt;strong&gt;5. Obsolescence of Algorithms&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;As computational power increases (especially with the advent of quantum computing), older algorithms like DES or MD5 become obsolete. Continuous updates and cryptographic agility are necessary to stay secure.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;the-future-of-encryption&quot;&gt;&lt;strong&gt;The Future of Encryption&lt;/strong&gt;&lt;/h5&gt;
&lt;hr&gt;
&lt;h4 id=&quot;1-post-quantum-cryptography&quot;&gt;&lt;strong&gt;1. Post-Quantum Cryptography&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Quantum computers pose a serious threat to current encryption methods, especially RSA and ECC. &lt;strong&gt;Post-quantum cryptography&lt;/strong&gt; aims to develop algorithms resistant to quantum attacks. NIST is currently evaluating new standards for this purpose.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;2-homomorphic-encryption&quot;&gt;&lt;strong&gt;2. Homomorphic Encryption&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;This emerging technology allows computation on encrypted data without decrypting it. This can revolutionize sectors like healthcare and finance, enabling secure data processing while preserving privacy.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;3-zero-knowledge-proofs-zkps-&quot;&gt;&lt;strong&gt;3. Zero-Knowledge Proofs (ZKPs)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;ZKPs allow one party to prove to another that they know a value (like a password) without revealing the actual value. This is particularly useful in decentralized systems and privacy-preserving authentication.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;4-decentralized-identity-and-encryption&quot;&gt;&lt;strong&gt;4. Decentralized Identity and Encryption&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;The concept of &lt;strong&gt;self-sovereign identity (SSI)&lt;/strong&gt; uses encryption to give individuals control over their personal data. Instead of relying on centralized authorities, users manage their credentials on a blockchain using encryption-based keys.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;5-ai-and-encryption&quot;&gt;&lt;strong&gt;5. AI and Encryption&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Artificial Intelligence (AI) is being explored to optimize encryption techniques by identifying potential vulnerabilities and adapting algorithms dynamically in real-time.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;best-practices-for-implementing-encryption&quot;&gt;&lt;strong&gt;Best Practices for Implementing Encryption&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;To maximize the effectiveness of encryption, certain best practices should be followed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;industry-standard&lt;/strong&gt; algorithms like AES, RSA, and SHA-2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotate encryption keys&lt;/strong&gt; periodically to limit exposure.&lt;/li&gt;
&lt;li&gt;Store encryption keys &lt;strong&gt;separately&lt;/strong&gt; from the encrypted data.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;multi-factor authentication (MFA)&lt;/strong&gt; to strengthen access controls.&lt;/li&gt;
&lt;li&gt;Apply encryption at &lt;strong&gt;both rest and transit&lt;/strong&gt; stages.&lt;/li&gt;
&lt;li&gt;Keep software and libraries &lt;strong&gt;updated&lt;/strong&gt; to patch known vulnerabilities.&lt;/li&gt;
&lt;li&gt;Perform &lt;strong&gt;regular audits and penetration tests&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h5 id=&quot;conclusion-2&quot;&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Encryption is more than just a technical tool—it is a vital guardian of privacy, trust, and freedom in the digital era. From securing your WhatsApp messages to protecting sensitive healthcare data, encryption safeguards our digital interactions. However, it is not a silver bullet. As threats evolve and technologies advance, so too must our cryptographic strategies.&lt;/p&gt;
&lt;p&gt;The future of encryption is promising, filled with innovations like homomorphic encryption, post-quantum cryptography, and AI-assisted security. But to truly benefit, individuals, businesses, and governments must embrace encryption with responsibility, adaptability, and foresight.&lt;/p&gt;
&lt;p&gt;By understanding its principles, applications, and challenges, we can better appreciate the silent yet powerful role encryption plays in our everyday lives.&lt;/p&gt;
</description>
<category>Data Privacy</category>
<guid isPermaLink="true">https://coderlegion.com/3173/understanding-encryption-data-privacy-security</guid>
<pubDate>Wed, 28 May 2025 04:19:18 +0000</pubDate>
</item>
</channel>
</rss>