AES Verschlüsselung mit Rust

AES macht Ihre Nachrichten sicher, indem es sie sie in ein Rätsel verwandelt, das nur mit dem richtigen Passwort gelöst werden kann.

AES steht für “Advanced Encryption Standard” und ist ein weit verbreiteter symmetrischer Verschlüsselungsalgorithmus, der in vielen Anwendungen und Systemen zur Sicherung von Daten verwendet wird. AES ist auch als Rijndael bekannt, benannt nach seinen Erfindern Vincent Rijmen und Joan Daemen.

Hier ist eine grundlegende Erklärung dessen, was AES ist und wie es funktioniert:

1. Symmetrische Verschlüsselung: AES ist ein symmetrischer Verschlüsselungsalgorithmus, was bedeutet, dass derselbe Schlüssel sowohl für die Verschlüsselung als auch für die Entschlüsselung verwendet wird. Dies steht im Gegensatz zur asymmetrischen Verschlüsselung, bei der separate Schlüssel für die Verschlüsselung und Entschlüsselung verwendet werden.

2. Blockverschlüsselung: AES ist ein Blockverschlüsselungsalgorithmus, was bedeutet, dass er Nachrichten in Blöcke fester Größe verschlüsselt. Die gebräuchlichen Blockgrößen sind 128, 192 und 256 Bits. Das bedeutet, dass für die Verschlüsselung und Entschlüsselung einer Nachricht diese in Blöcke der entsprechenden Größe aufgeteilt wird, und jeder Block separat verarbeitet wird.

3. Schlüssel: AES unterstützt verschiedene Schlüssellängen: 128 Bit, 192 Bit und 256 Bit. Die Sicherheit des Algorithmus hängt weitgehend von der Länge des verwendeten Schlüssels ab. Ein längerer Schlüssel bietet normalerweise einen höheren Schutz, aber er erfordert auch mehr Rechenleistung.

4. Runden: Der AES-Algorithmus verwendet eine bestimmte Anzahl von Runden (Rundenanzahl), um die Daten zu verschlüsseln und zu entschlüsseln. Die Anzahl der Runden hängt von der Schlüssellänge ab: 10 Runden für 128-Bit-Schlüssel, 12 Runden für 192-Bit-Schlüssel und 14 Runden für 256-Bit-Schlüssel.

5. Substitution, Permutation und XOR: Innerhalb jeder Runde führt AES verschiedene Transformationen auf den Daten durch, einschließlich Substitution (Ersetzen von Bytes), Permutation (Verschieben von Bytes innerhalb des Blocks) und XOR-Operationen (exklusives Oder) mit den Schlüsselbits. Diese Transformationen sind nichttrivial und bieten eine hohe Sicherheit gegenüber Angriffen.

6. Schlüsselplanung: Der Algorithmus verwendet auch einen speziellen Schlüsselplanungsmechanismus, um die Rundenschlüssel aus dem ursprünglichen Schlüssel abzuleiten.

7. Umkehrbarkeit: Ein wichtiger Aspekt von AES ist seine Umkehrbarkeit. Das bedeutet, dass die Verschlüsselung und Entschlüsselung mit demselben Schlüssel durchgeführt werden können, und die ursprünglichen Daten ohne Verlust wiederhergestellt werden können.

8. Anwendungen: AES wird in einer breiten Palette von Anwendungen eingesetzt, darunter die Sicherung von Daten in Computern und Netzwerken, die Verschlüsselung von Nachrichten in Kommunikationssystemen, die Sicherung von E-Mails, die Speicherung von Passwörtern und vieles mehr.

AES gilt als äußerst sicher und ist ein Standardverschlüsselungsalgorithmus, der von Regierungsbehörden, Unternehmen und Organisationen weltweit eingesetzt wird. Seine Sicherheit beruht auf der Komplexität seiner mathematischen Operationen, der Anzahl der Runden und der Schlüssellänge.

Ordnerstruktur

crypter
├── Cargo.toml
└── src
    ├── main.rs
    └── toolz
        ├── crypter
        │   └── mod.rs
        └── mod.rs

Cargo.toml

[package]
name = "crypter"
version = "0.1.0"
edition = "2021"

[dependencies]
aes = "0.8"

main.rs

mod toolz;

fn main() {
    //let key = [0u8; 16]; // Ihr geheimer Schlüssel hier
    //Die Zeile oben initialisiert den Schlüssel als ein Array von 16 Bytes, wobei jedes Byte den Wert 0 hat. 
    let key = [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10];
    
    let plaintext = b"Dies ist ein Beispieltext.";      // Byte-Literal
    // Ein Byte-Literal ist eine Sequenz von Bytes, die normalerweise als ASCII-Zeichen oder andere Dateninterpretationen behandelt werden.
    // Dies bedeutet, dass der String nicht als Unicode-Zeichenkette interpretiert wird, sondern als eine Sequenz von Bytes.
    
    // Verschlüsseln der Daten
    let encrypted_data = toolz::crypter::encrypt_128bit(plaintext, &key);
    
    // Entschlüsseln der Daten
    let decrypted_data = toolz::crypter::decrypt_128bit(&encrypted_data, &key);
    
    // Ausgabe der Ergebnisse
    println!("Originaltext: {:?}", String::from_utf8_lossy(plaintext));
    println!("Verschlüsselter Text: {:?}", encrypted_data);
    println!("Entschlüsselter Text: {:?}", String::from_utf8_lossy(&decrypted_data));
    println!("Verwendeter Schlüssel: {:?}", key);
}

src/toolz/mod.rs

pub mod crypter;

src/toolz/crypter/mod.rs

use aes::Aes128;
use aes::cipher::{BlockEncrypt, BlockDecrypt, KeyInit, generic_array::GenericArray};

// Funktion zum Verschlüsseln von Daten
pub fn encrypt_128bit(data: &[u8], key: &[u8; 16]) -> Vec<u8> {
    // Erstelle einen AES-128-Verschlüsselungsalgorithmus mit dem gegebenen Schlüssel
    let cipher = Aes128::new(GenericArray::from_slice(key));
    
    // Erstelle einen Vektor, um die verschlüsselten Daten zu speichern
    let mut encrypted_data = Vec::new();
    
    // Padden der Daten auf ein Vielfaches von 16 Bytes
    let padded_data = if data.len() % 16 != 0 {
        let padding_size = 16 - (data.len() % 16);
        let mut padded = Vec::from(data);
        padded.extend(vec![padding_size as u8; padding_size]);
        padded
    } else {
        Vec::from(data)
    };
    
    // Verarbeite die Daten blockweise und verschlüssele sie
    for chunk in padded_data.chunks(16) {
        let mut block = GenericArray::clone_from_slice(chunk);
        cipher.encrypt_block(&mut block);
        encrypted_data.extend_from_slice(&block);
    }
    
    encrypted_data
}

// Funktion zum Entschlüsseln von Daten
pub fn decrypt_128bit(encrypted_data: &[u8], key: &[u8; 16]) -> Vec<u8> {
    // Erstelle einen AES-128-Entschlüsselungsalgorithmus mit dem gegebenen Schlüssel
    let cipher = Aes128::new(GenericArray::from_slice(key));
    
    // Erstelle einen Vektor, um die entschlüsselten Daten zu speichern
    let mut decrypted_data = Vec::new();
    
    // Verarbeite die verschlüsselten Daten blockweise und entschlüssele sie
    for chunk in encrypted_data.chunks(16) {
        let mut block = GenericArray::clone_from_slice(chunk);
        cipher.decrypt_block(&mut block);
        decrypted_data.extend_from_slice(&block);
    }
    
    // Entfernen des Paddings am Ende
    if !decrypted_data.is_empty() {
        let padding_size = decrypted_data[decrypted_data.len() - 1] as usize;
        decrypted_data.truncate(decrypted_data.len() - padding_size);
    }
    
    decrypted_data
}

cargo run

    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/crypter`
Originaltext: "Dies ist ein Beispieltext."
Verschlüsselter Text: [115, 130, 235, 252, 159, 224, 22, 97, 95, 152, 170, 59, 146, 17, 70, 174, 149, 39, 145, 179, 134, 123, 141, 96, 25, 186, 3, 200, 23, 76, 135, 56]
Entschlüsselter Text: "Dies ist ein Beispieltext."
Verwendeter Schlüssel: [18, 52, 86, 120, 144, 171, 205, 239, 254, 220, 186, 152, 118, 84, 50, 16]

Siehe auch

AES-Verschlüsselung mit OpenSSL, Perl und PHP.
docs.rs/aes Crate aes