Migration Deep Dive für 32 · Kryptografie öffnen →
⌂ ÜbersichtAlle Vergleiche
Modul 32 · 100 % Codeabdeckung

Kryptografie

Vollständiger Legacy-Modern-Vergleich aller Java-Klassen, Tests, Maven-POMs und relevanten Ressourcen dieses Moduls. Jede Datei ist genau einmal einer fachlich passenden Vergleichsgruppe zugeordnet.

3Legacy-Dateien
4Modern-Dateien
75 → 103Codezeilen
8/8vollständig erfasst

Fachliche Einordnung

Legacy

AES/ECB ohne Authentifizierung

ECB verschlüsselt gleiche Klartextblöcke identisch und erkennt Manipulation nicht.

Modern

AES/GCM mit zufälligem Nonce

GCM liefert Vertraulichkeit und Integrität; ein zufälliger Nonce wird mit dem Ciphertext gespeichert.

Vergleichsfokus: Alle Dateien werden nach technischer Rolle und fachlicher Verantwortung gruppiert.
Wichtige Abgrenzung: One-to-many-Änderungen werden als Gruppe dargestellt; eine künstliche 1:1-Zuordnung wird vermieden.

Vollständige Abdeckungsmatrix

Die Ähnlichkeit ist eine technische Orientierung auf normalisiertem Quelltext. Sie ersetzt keine fachliche Bewertung.

VergleichsgruppeLegacy-DateienModern-DateienLegacy-ZeilenModern-ZeilenÄhnlichkeit
Build-Konfiguration113434100%
Verschlüsselungsservice, Payload und Test23416941%

Gemeinsame Modulstruktur

Das Pair-POM bindet die Legacy- und Modern-Submodule zusammen und gehört deshalb ebenfalls zur vollständigen Codeabdeckung.

Gemeinsam · 19 Zeilenpom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>at.aydin.academy</groupId>
        <artifactId>java-modernization-deep-dive</artifactId>
        <version>1.0.0</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <artifactId>32crypto-pair</artifactId>
    <packaging>pom</packaging>
    <name>Kryptografie: Legacy und Modern</name>
    <modules>
        <module>legacy</module>
        <module>modern</module>
    </modules>
</project>

Alle semantischen Codevergleiche

01Build-KonfigurationDirektvergleich · Legacy 34 / Modern 34 Zeilen · Ähnlichkeit 100%

Crypto-/Testkonfiguration wird verglichen.

Legacy-DateienModern-DateienEinordnung
pom.xmlpom.xmlDirektvergleich
Semantische Ähnlichkeit: 100%

Legacy

Legacy · 34 Zeilenlegacy/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <parent>
                <groupId>at.aydin.academy</groupId>
                <artifactId>32crypto-pair</artifactId>
                <version>1.0.0</version>
                <relativePath>../pom.xml</relativePath>
            </parent>
            <artifactId>crypto-legacy</artifactId>
            <packaging>jar</packaging>
            <name>Crypto Legacy</name>

            <dependencies>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>

            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                    </plugin>

                </plugins>
            </build>
        </project>

Modern

Modern · 34 Zeilenmodern/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <parent>
                <groupId>at.aydin.academy</groupId>
                <artifactId>32crypto-pair</artifactId>
                <version>1.0.0</version>
                <relativePath>../pom.xml</relativePath>
            </parent>
            <artifactId>crypto-modern</artifactId>
            <packaging>jar</packaging>
            <name>Crypto Modern</name>

            <dependencies>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>

            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                    </plugin>

                </plugins>
            </build>
        </project>
02Verschlüsselungsservice, Payload und TestDirektvergleich · Legacy 41 / Modern 69 Zeilen · Ähnlichkeit 41%

ECB ohne Authentisierung wird GCM mit IV und authentisiertem Payload gegenübergestellt.

Legacy-DateienModern-DateienEinordnung
LegacyAesEcb.java
LegacyAesEcbTest.java
AesGcmService.java
EncryptedPayload.java
AesGcmServiceTest.java
Direktvergleich
Semantische Ähnlichkeit: 41%

Legacy

package at.aydin.lab.crypto.legacy;

// Design Pattern: Security Gateway (Legacy-Antipattern) – bündelt Kryptografie, verwendet absichtlich unsicheres ECB.
import javax.crypto.*;
import javax.crypto.spec.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;

/** Lern-Antipattern: AES/ECB ist deterministisch und für produktive Daten ungeeignet. */
public final class LegacyAesEcb {
    private SecretKey key(String password) throws Exception {
        return new SecretKeySpec(Arrays.copyOf(MessageDigest.getInstance("SHA-256").digest(password.getBytes(StandardCharsets.UTF_8)),
            16), "AES");
    }

    public String encrypt(String text, String password) throws Exception {
        Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
        c.init(Cipher.ENCRYPT_MODE, key(password));
        return Base64.getEncoder().encodeToString(c.doFinal(text.getBytes(StandardCharsets.UTF_8)));
    }

    public String decrypt(String value, String password) throws Exception {
        Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
        c.init(Cipher.DECRYPT_MODE, key(password));
        return new String(c.doFinal(Base64.getDecoder().decode(value)), StandardCharsets.UTF_8);
    }
}
package at.aydin.lab.crypto.legacy;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class LegacyAesEcbTest {
    @Test
    void isDeterministicAntiPattern() throws Exception {
        var c = new LegacyAesEcb();
        assertEquals(c.encrypt("text", "pw"), c.encrypt("text", "pw"));
        assertEquals("text", c.decrypt(c.encrypt("text", "pw"), "pw"));
    }
}

Modern

package at.aydin.lab.crypto.modern;

import javax.crypto.*;
import javax.crypto.spec.*;
import java.nio.charset.StandardCharsets;
import java.security.*;

// Design Pattern: Security Gateway
// Zweck: Sichere kryptografische Parameter werden zentral erzwungen.
public final class AesGcmService {
    private final SecureRandom random = new SecureRandom();
    private SecretKey key(char[] password, byte[] salt) throws Exception {
        var f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        return new SecretKeySpec(f.generateSecret(new PBEKeySpec(password, salt, 120_000, 256)).getEncoded(), "AES");
    }

    public EncryptedPayload encrypt(String text, char[] password) throws Exception {
        byte[] salt = new byte[16], iv = new byte[12];
        random.nextBytes(salt);
        random.nextBytes(iv);
        Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
        c.init(Cipher.ENCRYPT_MODE, key(password, salt), new GCMParameterSpec(128, iv));
        return new EncryptedPayload(salt, iv, c.doFinal(text.getBytes(StandardCharsets.UTF_8)));
    }

    public String decrypt(EncryptedPayload p, char[] password) throws Exception {
        Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
        c.init(Cipher.DECRYPT_MODE, key(password, p.salt()), new GCMParameterSpec(128, p.iv()));
        return new String(c.doFinal(p.cipherText()), StandardCharsets.UTF_8);
    }
}
package at.aydin.lab.crypto.modern;

// Design Pattern: Value Object
// Zweck: Ciphertext, Salt und IV bleiben als untrennbare verschlüsselte Nutzlast zusammen.
public record EncryptedPayload(byte[] salt, byte[] iv, byte[] cipherText) {
    public EncryptedPayload {
        salt = salt.clone();
        iv = iv.clone();
        cipherText = cipherText.clone();
    }

    public byte[] salt() {
        return salt.clone();
    }

    public byte[] iv() {
        return iv.clone();
    }

    public byte[] cipherText() {
        return cipherText.clone();
    }
}
package at.aydin.lab.crypto.modern;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AesGcmServiceTest {
    @Test
    void encryptsRandomizedAndAuthenticated() throws Exception {
        var s = new AesGcmService();
        var a = s.encrypt("text", "pw".toCharArray());
        var b = s.encrypt("text", "pw".toCharArray());
        assertFalse(java.util.Arrays.equals(a.cipherText(), b.cipherText()));
        assertEquals("text", s.decrypt(a, "pw".toCharArray()));
    }
}
⌂ Cockpit