What is .NET string encryption in practice?
In a typical .NET application, every string literal, error messages, SQL queries, API keys, internal protocol commands, ends up stored in the assembly metadata in plain text. A decompiler can list them instantly. String encryption is an obfuscation technique that transforms those literals into encrypted blobs and adds a small runtime routine that decrypts them only when needed.
From the perspective of your source code, you still write normal strings. The obfuscation step rewrites the compiled IL, injects an encryption key and algorithm, and replaces each literal with a call to a decryption helper. Attackers who inspect the binary see opaque data instead of meaningful text.
Step‑by‑step: how encryption is applied
1. Scan and collect string literals
The obfuscator analyzes the compiled assembly and finds all string literals that should be protected. You can usually configure which namespaces, classes, or attributes are in scope.
2. Encrypt each string with a key
For every selected literal, the tool applies a symmetric encryption algorithm (for example, AES or a custom variant) using a key that is embedded or derived at runtime. The result is binary ciphertext, often stored as a byte array or encoded string.
3. Rewrite IL to use a decryption helper
Instead of loading the original literal, the IL is modified to load the encrypted data and call a
helper method like DecryptString(int id) or Decrypt(byte[] data). That helper
contains the decryption logic and any key derivation.
4. Decrypt on demand at runtime
When the application runs and reaches the string usage, the helper decrypts the ciphertext in memory and returns the original text. The decrypted value typically lives only in RAM and is not stored back into the assembly.
5. Optional: cache or re‑encrypt
Some implementations cache decrypted strings for performance, while others avoid caching to reduce the window in which sensitive data is present in memory. Advanced obfuscators may also randomize keys or use per‑string keys to complicate analysis.
Example pattern in C# (conceptual)
// Original code
string message = "License validation failed";
// After obfuscation (conceptual)
string message = StringDecryptor.Decrypt(0x12AF); // 0x12AF indexes encrypted data
// Decryptor (simplified)
internal static class StringDecryptor
{
public static string Decrypt(int id)
{
byte[] cipher = StringTable.GetCipher(id);
byte[] key = KeyDerivation.GetKey();
byte[] plain = AesLikeDecrypt(cipher, key);
return System.Text.Encoding.UTF8.GetString(plain);
}
}
String encryption flow (@graph structure)
The diagram below shows the logical flow from your source code to runtime decryption as a simple graph.