Feedback

Encrypt and Decrypt Strings

Sprache: C#

This class encrypt and decrypt strings using the Rijndael algorithm .
using System;
using System.IO;
using System.Security.Cryptography;

/// <summary>
/// encrypt and decrypt strings
/// </summary>
public class Encryption
{
    /// <summary>
    /// Encrypts the string.
    /// </summary>
    /// <param name="clearText">The clear text.</param>
    /// <param name="Key">The key.</param>
    /// <param name="IV">The IV.</param>
    /// <returns></returns>
    private static byte[] EncryptString(byte[] clearText, byte[] Key, byte[] IV)
    {
        MemoryStream ms = new MemoryStream();
        Rijndael alg = Rijndael.Create();
        alg.Key = Key;
        alg.IV = IV;
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(clearText, 0, clearText.Length);
        cs.Close();
        byte[] encryptedData = ms.ToArray();
        return encryptedData;
    }

    /// <summary>
    /// Encrypts the string.
    /// </summary>
    /// <param name="clearText">The clear text.</param>
    /// <param name="Password">The password.</param>
    /// <returns></returns>
    public static string EncryptString(string clearText, string Password)
    {
        byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        byte[] encryptedData = EncryptString(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
        return Convert.ToBase64String(encryptedData);
    }

    /// <summary>
    /// Decrypts the string.
    /// </summary>
    /// <param name="cipherData">The cipher data.</param>
    /// <param name="Key">The key.</param>
    /// <param name="IV">The IV.</param>
    /// <returns></returns>
    private static byte[] DecryptString(byte[] cipherData, byte[] Key, byte[] IV)
    {
        MemoryStream ms = new MemoryStream();
        Rijndael alg = Rijndael.Create();
        alg.Key = Key;
        alg.IV = IV;
        CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(cipherData, 0, cipherData.Length);
        cs.Close();
        byte[] decryptedData = ms.ToArray();
        return decryptedData;
    }

    /// <summary>
    /// Decrypts the string.
    /// </summary>
    /// <param name="cipherText">The cipher text.</param>
    /// <param name="Password">The password.</param>
    /// <returns></returns>
    public static string DecryptString(string cipherText, string Password)
    {
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        byte[] decryptedData = DecryptString(cipherBytes, pdb.GetBytes(32), pdb.GetBytes(16));
        return System.Text.Encoding.Unicode.GetString(decryptedData);
    }
}
using System;
using System.IO;
using System.Security.Cryptography;

/// <summary>
/// encrypt and decrypt strings
/// </summary>
public class Encryption
{
    /// <summary>
    /// Encrypts the string.
    /// </summary>
    /// <param name="clearText">The clear text.</param>
    /// <param name="Key">The key.</param>
    /// <param name="IV">The IV.</param>
    /// <returns></returns>
    private static byte[] EncryptString(byte[] clearText, byte[] Key, byte[] IV)
    {
        MemoryStream ms = new MemoryStream();
        Rijndael alg = Rijndael.Create();
        alg.Key = Key;
        alg.IV = IV;
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(clearText, 0, clearText.Length);
        cs.Close();
        byte[] encryptedData = ms.ToArray();
        return encryptedData;
    }

    /// <summary>
    /// Encrypts the string.
    /// </summary>
    /// <param name="clearText">The clear text.</param>
    /// <param name="Password">The password.</param>
    /// <returns></returns>
    public static string EncryptString(string clearText, string Password)
    {
        byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        byte[] encryptedData = EncryptString(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
        return Convert.ToBase64String(encryptedData);
    }

    /// <summary>
    /// Decrypts the string.
    /// </summary>
    /// <param name="cipherData">The cipher data.</param>
    /// <param name="Key">The key.</param>
    /// <param name="IV">The IV.</param>
    /// <returns></returns>
    private static byte[] DecryptString(byte[] cipherData, byte[] Key, byte[] IV)
    {
        MemoryStream ms = new MemoryStream();
        Rijndael alg = Rijndael.Create();
        alg.Key = Key;
        alg.IV = IV;
        CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(cipherData, 0, cipherData.Length);
        cs.Close();
        byte[] decryptedData = ms.ToArray();
        return decryptedData;
    }

    /// <summary>
    /// Decrypts the string.
    /// </summary>
    /// <param name="cipherText">The cipher text.</param>
    /// <param name="Password">The password.</param>
    /// <returns></returns>
    public static string DecryptString(string cipherText, string Password)
    {
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        byte[] decryptedData = DecryptString(cipherBytes, pdb.GetBytes(32), pdb.GetBytes(16));
        return System.Text.Encoding.Unicode.GetString(decryptedData);
    }
}

7 Kommentare

  1. Ich kenne mich mit dem Thema nicht so aus aber muss man für „cipherText“ einfach irgend eine belibige Zeichenfolge wählen? Und muss bei „clearText“ die gleiche Zeichenfolge stehen?

  2. Hey, Ho..
    Ich wüsste jetzt auch nicht wirklich was in den cipherText soll..
    Kanns grad nicht ausprobiern weil ich grad nur mit dem Eier-Pad on bin..
    Kann mir jemand weiterhelfen??
    Vielleicht ja Herr Welker persönlich?! 😉 😉

  3. Ups! Ist ja logisch..
    Ich wollt’s grad ausprobieren und hab mich gefragt, woher weiß die Methode eigentlich was sie Entschlüsseln soll..??
    >>Cipher Text<< 😀 Naja.. kommt vor. Einfach auf dem Schlauch gestanden.

  4. Das Snippet ist von 2006 und zeigt einen damals verbreiteten Ansatz: Rijndael per CryptoStream, Key und IV werden als Byte-Arrays übergeben und der resultierende Ciphertext als Byte[] zurückgegeben. Inhaltlich ist „String verschlüsseln/entschlüsseln“ weiterhin ein Standard-Problem, aber die damalige Umsetzung lässt heute zu viele wichtige Details offen (Authentizität, Key-Derivation, IV-Handling, Fehlermodi) und lädt in realen Anwendungen schnell zu unsicheren Nutzungsweisen ein.

    [b]Analyse nach heutigen Kriterien:[/b]
    – [u]Sicherheit[/u]: Symmetrische Verschlüsselung ohne Authentifizierung ist gefährlich. Moderne Anwendungen sollten AEAD verwenden (z. B. AES-GCM), damit Vertraulichkeit und Integrität gemeinsam abgesichert sind.
    – [u]Korrektheit[/u]: Rijndael ist nicht automatisch AES. AES ist Rijndael mit fester Blockgröße von 128 Bit. Für Interoperabilität sollte Aes statt Rijndael.Create verwendet werden.
    – [u]Key/IV-Handling[/u]: Das Snippet überlässt Key- und IV-Erzeugung dem Aufrufer. IVs müssen pro Verschlüsselung zufällig sein, Keys aus Passwörtern müssen über PBKDF2 abgeleitet werden.
    – [u]Robustheit[/u]: Streams werden nicht deterministisch freigegeben. Fehlerpfade sind unklar, Exceptions werden nicht differenziert behandelt.
    – [u]Cloud/Container[/u]: Moderne Crypto-APIs sind plattformübergreifend verfügbar, entscheidend ist sauberes Key-Management (Secrets nicht im Code oder in Dateien ablegen).
    – [u]Thread-Safety[/u]: Pro Aufruf erzeugte Crypto-Instanzen sind thread-safe nutzbar, statische Instanzen wären problematisch.

    [b]Modernisierte Variante (AES-GCM, PBKDF2, Base64-Payload):[/b]
    [code]
    using System;
    using System.Security.Cryptography;
    using System.Text;

    public static class StringEncryption
    {
    public static string EncryptToBase64(string plaintext, string password)
    {
    byte[] salt = RandomNumberGenerator.GetBytes(16);
    byte[] nonce = RandomNumberGenerator.GetBytes(12);

    using var kdf = new Rfc2898DeriveBytes(password, salt, 150_000, HashAlgorithmName.SHA256);
    byte[] key = kdf.GetBytes(32);

    byte[] plainBytes = Encoding.UTF8.GetBytes(plaintext);
    byte[] cipherBytes = new byte[plainBytes.Length];
    byte[] tag = new byte[16];

    using var aes = new AesGcm(key);
    aes.Encrypt(nonce, plainBytes, cipherBytes, tag);

    byte[] payload = new byte[1 + salt.Length + nonce.Length + tag.Length + cipherBytes.Length];
    payload[0] = 1;
    Buffer.BlockCopy(salt, 0, payload, 1, salt.Length);
    Buffer.BlockCopy(nonce, 0, payload, 1 + salt.Length, nonce.Length);
    Buffer.BlockCopy(tag, 0, payload, 1 + salt.Length + nonce.Length, tag.Length);
    Buffer.BlockCopy(cipherBytes, 0, payload, 1 + salt.Length + nonce.Length + tag.Length, cipherBytes.Length);

    CryptographicOperations.ZeroMemory(key);
    return Convert.ToBase64String(payload);
    }

    public static string DecryptFromBase64(string base64Payload, string password)
    {
    byte[] payload = Convert.FromBase64String(base64Payload);

    int offset = 1;
    byte[] salt = new byte[16];
    Buffer.BlockCopy(payload, offset, salt, 0, salt.Length);
    offset += salt.Length;

    byte[] nonce = new byte[12];
    Buffer.BlockCopy(payload, offset, nonce, 0, nonce.Length);
    offset += nonce.Length;

    byte[] tag = new byte[16];
    Buffer.BlockCopy(payload, offset, tag, 0, tag.Length);
    offset += tag.Length;

    byte[] cipher = new byte[payload.Length – offset];
    Buffer.BlockCopy(payload, offset, cipher, 0, cipher.Length);

    using var kdf = new Rfc2898DeriveBytes(password, salt, 150_000, HashAlgorithmName.SHA256);
    byte[] key = kdf.GetBytes(32);

    byte[] plainBytes = new byte[cipher.Length];
    using var aes = new AesGcm(key);
    aes.Decrypt(nonce, cipher, tag, plainBytes);

    CryptographicOperations.ZeroMemory(key);
    return Encoding.UTF8.GetString(plainBytes);
    }
    }
    [/code]

    [b]Warum das heute objektiv besser ist:[/b]
    – [u]Sicherheit[/u]: Authentifizierte Verschlüsselung verhindert stille Manipulationen.
    – [u]Key-Management[/u]: Klare Strategie für Salt, Nonce und Passwort-Ableitung.
    – [u]Plattformtauglichkeit[/u]: Läuft unverändert auf Windows, Linux und macOS.
    – [u]Wartbarkeit[/u]: Versionierbares Payload-Format und klarer Verantwortungsbereich.

    [b]Security-Realitätscheck:[/b]
    Verschlüsselung ersetzt kein echtes Secret-Management. Für produktive Systeme gehören Schlüssel in dedizierte Secret-Stores oder Key Vaults.