Skip to content
IRC-CodingIRC-Coding
Cybersecurity FundamentalsCryptography EncryptionHash FunctionsDigital SignaturesRSA AESAlgorithmsAlgorithmFundamentals

Cybersecurity Fundamentals: Cryptography & Encryption

Master cybersecurity essentials: symmetric/asymmetric encryption, RSA, AES, hash functions, digital signatures & SSL/TLS with practical examples.

S

schutzgeist

16 min read
Cybersecurity Fundamentals: Cryptography & Encryption

Cybersecurity Fundamentals: Cryptography, Encryption, Hash Functions & Digital Signatures

This guide is a comprehensive introduction to cybersecurity fundamentals – covering cryptography, encryption, hash functions, and digital signatures with practical examples.

In a Nutshell

Cryptography protects data through encryption, hash functions ensure integrity, and digital signatures guarantee authenticity. Modern security rests on mathematical algorithms.

Core Technical Overview

Cryptography is the science of encrypting and decrypting information to protect it from unauthorized access.

Key Areas:

Symmetric Encryption

  • Concept: Same key for both encryption and decryption
  • Algorithms: AES, DES, 3DES, Blowfish
  • Advantages: Fast, efficient for large datasets
  • Drawbacks: Key distribution remains challenging

Asymmetric Encryption

  • Concept: Public and private key pairs
  • Algorithms: RSA, ECC, DSA, ElGamal
  • Advantages: Secure key distribution
  • Drawbacks: Slower, computationally intensive

Hash Functions

  • Concept: One-way function producing a digital fingerprint
  • Algorithms: SHA-256, SHA-3, MD5 (deprecated), bcrypt
  • Properties: Collision resistance, preimage resistance
  • Applications: Password hashing, data integrity verification

Digital Signatures

  • Concept: Cryptographic signature ensuring authenticity
  • Process: Hash → Encrypt with private key
  • Verification: Decrypt with public key → Compare hash
  • Standards: RSA, DSA, ECDSA

S/MIME

S/MIME is a standard for encrypting and digitally signing emails. It uses asymmetric cryptography and relies on certificates to authenticate both sender and recipient. When you encrypt an email with S/MIME, the content becomes readable only with the recipient’s private key. A digital signature confirms that the message genuinely came from you and hasn’t been tampered with. Many enterprises deploy S/MIME because it protects the confidentiality and integrity of email communications.

Exam-Relevant Key Points

  • Cryptography: Science of secure communication
  • Symmetric Encryption: AES, single key for both directions
  • Asymmetric Encryption: RSA, public/private key pairs
  • Hash Functions: SHA-256, one-way hash for integrity
  • Digital Signatures: RSA/ECDSA, authenticity and integrity
  • SSL/TLS: Encrypted web communication
  • IHK-relevant: Foundation for IT security and data protection

Core Components

  1. Encryption: Protecting confidentiality
  2. Hash Functions: Ensuring integrity
  3. Digital Signatures: Guaranteeing authenticity
  4. Public Key Infrastructure: Key management
  5. SSL/TLS: Secure network communication
  6. Cryptographic Protocols: Secure data transmission
  7. Key Management: Generation, storage, distribution
  8. Security Best Practices: Implementation and deployment

Practical Examples

1. Symmetric Encryption with AES

import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.util.Base64;

public class SymmetricEncryptionDemo {
    
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static final int KEY_LENGTH = 256;
    private static final int IV_LENGTH = 16;
    
    // Generate AES key
    public static SecretKey generateAESKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(KEY_LENGTH);
        return keyGenerator.generateKey();
    }
    
    // Generate initialization vector (IV)
    public static byte[] generateIV() {
        byte[] iv = new byte[IV_LENGTH];
        new SecureRandom().nextBytes(iv);
        return iv;
    }
    
    // Encrypt data
    public static String encryptAES(String plaintext, SecretKey key, byte[] iv) 
            throws Exception {
        
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
        
        // Combine IV and encrypted data
        byte[] combined = new byte[iv.length + encryptedBytes.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encryptedBytes, 0, combined, iv.length, encryptedBytes.length);
        
        return Base64.getEncoder().encodeToString(combined);
    }
    
    // Decrypt data
    public static String decryptAES(String ciphertext, SecretKey key) throws Exception {
        byte[] combined = Base64.getDecoder().decode(ciphertext);
        
        // Extract IV
        byte[] iv = new byte[IV_LENGTH];
        System.arraycopy(combined, 0, iv, 0, iv.length);
        
        // Extract encrypted data
        byte[] encryptedBytes = new byte[combined.length - iv.length];
        System.arraycopy(combined, iv.length, encryptedBytes, 0, encryptedBytes.length);
        
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
        
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }
    
    // AES-256 demo
    public static void aesDemo() {
        try {
            System.out.println("=== AES-256 Encryption Demo ===");
            
            // Generate key
            SecretKey aesKey = generateAESKey();
            System.out.println("AES-256 key generated");
            System.out.println("Key (Base64): " + Base64.getEncoder().encodeToString(aesKey.getEncoded()));
            
            // Test data
            String plaintext = "This is a secret message being encrypted with AES-256.";
            System.out.println("\nPlaintext: " + plaintext);
            
            // Encrypt
            byte[] iv = generateIV();
            String ciphertext = encryptAES(plaintext, aesKey, iv);
            System.out.println("\nEncrypted: " + ciphertext);
            
            // Decrypt
            String decryptedText = decryptAES(ciphertext, aesKey);
            System.out.println("\nDecrypted: " + decryptedText);
            
            // Verify
            System.out.println("\nEncryption successful: " + plaintext.equals(decryptedText));
            
        } catch (Exception e) {
            System.err.println("Error during AES encryption: " + e.getMessage());
        }
    }
    
    // Performance comparison of different AES modes
    public static void compareAESModes() {
        try {
            System.out.println("\n=== AES Modes Performance Comparison ===");
            
            String[] modes = {"AES/ECB/PKCS5Padding", "AES/CBC/PKCS5Padding", 
                              "AES/GCM/NoPadding", "AES/CFB/PKCS5Padding"};
            
            SecretKey key = generateAESKey();
            String testData = "Performance test data for various AES modes. ".repeat(100);
            
            for (String mode : modes) {
                long startTime = System.nanoTime();
                
                try {
                    Cipher cipher = Cipher.getInstance(mode);
                    
                    if (mode.contains("ECB")) {
                        cipher.init(Cipher.ENCRYPT_MODE, key);
                    } else {
                        byte[] iv = generateIV();
                        IvParameterSpec ivSpec = new IvParameterSpec(iv);
                        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
                    }
                    
                    byte[] encrypted = cipher.doFinal(testData.getBytes());
                    
                    long endTime = System.nanoTime();
                    long duration = (endTime - startTime) / 1_000_000; // ms
                    
                    System.out.printf("%-25s: %dms (%d bytes)%n", 
                                     mode, duration, encrypted.length);
                    
                } catch (Exception e) {
                    System.out.printf("%-25s: Error - %s%n", mode, e.getMessage());
                }
            }
            
        } catch (Exception e) {
            System.err.println("Error during performance comparison: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        aesDemo();
        compareAESModes();
    }
}

2. Asymmetric Encryption with RSA

import javax.crypto.*;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

public class AsymmetricEncryptionDemo {
    
    private static final String ALGORITHM = "RSA";
    private static final int KEY_SIZE = 2048;
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    
    // Generate RSA key pair
    public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyGen.initialize(KEY_SIZE);
        return keyGen.generateKeyPair();
    }
    
    // Encrypt with public key
    public static String encryptRSA(String plaintext, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    
    // Decrypt with private key
    public static String decryptRSA(String ciphertext, PrivateKey privateKey) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(ciphertext);
        
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }
    
    // Create digital signature
    public static String signData(String data, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data.getBytes());
        
        byte[] signatureBytes = signature.sign();
        return Base64.getEncoder().encodeToString(signatureBytes);
    }
    
    // Verify digital signature
    public static boolean verifySignature(String data, String signatureStr, PublicKey publicKey) 
            throws Exception {
        
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(data.getBytes());
        
        byte[] signatureBytes = Base64.getDecoder().decode(signatureStr);
        return signature.verify(signatureBytes);
    }
    
    // RSA demo
    public static void rsaDemo() {
        try {
            System.out.println("=== RSA Encryption Demo ===");
            
            // Generate key pair
            KeyPair keyPair = generateRSAKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();
            
            System.out.println("RSA-2048 key pair generated");
            System.out.println("Public Key: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));
            System.out.println("Private Key: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));
            
            // Test data
            String plaintext = "This message is encrypted with RSA-2048 and digitally signed.";
            System.out.println("\nPlaintext: " + plaintext);
            
            // Encrypt with public key
            String ciphertext = encryptRSA(plaintext, publicKey);
            System.out.println("\nEncrypted (Public Key): " + ciphertext);
            
            // Decrypt with private key
            String decryptedText = decryptRSA(ciphertext, privateKey);
            System.out.println("Decrypted (Private Key): " + decryptedText);
            
            // Create digital signature
            String signature = signData(plaintext, privateKey);
            System.out.println("\nDigital Signature: " + signature);
            
            // Verify signature
            boolean isValid = verifySignature(plaintext, signature, publicKey);
            System.out.println("Signature valid: " + isValid);
            
            // Test tampered signature
            String manipulatedData = plaintext + " (tampered)";
            boolean isManipulatedValid = verifySignature(manipulatedData, signature, publicKey);
            System.out.println("Tampered signature valid: " + isManipulatedValid);
            
        } catch (Exception e) {
            System.err.println("Error during RSA encryption: " + e.getMessage());
        }
    }
    
    // Hybrid encryption (RSA + AES)
    public static void hybridEncryptionDemo() {
        try {
            System.out.println("\n=== Hybrid Encryption Demo (RSA + AES) ===");
            
            // Generate keys
            KeyPair rsaKeyPair = generateRSAKeyPair();
            SecretKey aesKey = SymmetricEncryptionDemo.generateAESKey();
            
            // Large dataset
            String largeData = "This is a large dataset that will be encrypted with AES, and then the AES key will be encrypted with RSA. ".repeat(50);
            System.out.println("Original data size: " + largeData.length() + " characters");
            
            // Step 1: Encrypt data with AES
            byte[] iv = SymmetricEncryptionDemo.generateIV();
            String encryptedData = SymmetricEncryptionDemo.encryptAES(largeData, aesKey, iv);
            System.out.println("Encrypted with AES: " + encryptedData.length() + " characters");
            
            // Step 2: Encrypt AES key with RSA
            String encryptedKey = encryptRSA(Base64.getEncoder().encodeToString(aesKey.getEncoded()), rsaKeyPair.getPublic());
            System.out.println("AES key encrypted with RSA");
            
            // Step 3: Decryption (reverse order)
            String decryptedKey = decryptRSA(encryptedKey, rsaKeyPair.getPrivate());
            byte[] decodedKey = Base64.getDecoder().decode(decryptedKey);
            SecretKey restoredAESKey = new SecretKeySpec(decodedKey, "AES");
            
            String decryptedData = SymmetricEncryptionDemo.decryptAES(encryptedData, restoredAESKey);
            
            System.out.println("Hybrid encryption successful: " + largeData.equals(decryptedData));
            
        } catch (Exception e) {
            System.err.println("Error during hybrid encryption: " + e.getMessage());
        }
    }
    
    // Compare RSA key sizes
    public static void compareKeySizes() {
        try {
            System.out.println("\n=== RSA Key Size Comparison ===");
            
            int[] keySizes = {1024, 2048, 4096};
            String testData = "Test data for key size comparison";
            
            for (int keySize : keySizes) {
                try {
                    KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
                    keyGen.initialize(keySize);
                    KeyPair keyPair = keyGen.generateKeyPair();
                    
                    long startTime = System.nanoTime();
                    String encrypted = encryptRSA(testData, keyPair.getPublic());
                    long encryptTime = System.nanoTime() - startTime;
                    
                    startTime = System.nanoTime();
                    String decrypted = decryptRSA(encrypted, keyPair.getPrivate());
                    long decryptTime = System.nanoTime() - startTime;
                    
                    System.out.printf("RSA-%d: Encryption %dms, Decryption %dms%n",
                                     keySize, encryptTime / 1_000_000, decryptTime / 1_000_000);
                    
                } catch (Exception e) {
                    System.out.printf("RSA-%d: Error - %s%n", keySize, e.getMessage());
                }
            }
            
        } catch (Exception e) {
            System.err.println("Error during key size comparison: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        rsaDemo();
        hybridEncryptionDemo();
        compareKeySizes();
    }
}

3. Hash Functions and Password Security

import java.security.*;
import java.util.Base64;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.Arrays;

public class HashFunctionsDemo {
    
    private static final String SHA_256 = "SHA-256";
    private static final String SHA_3_256 = "SHA3-256";
    private static final String BCRYPT = "BCrypt";
    
    // Calculate SHA-256 hash
    public static String sha256(String input) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance(SHA_256);
        byte[] hashBytes = digest.digest(input.getBytes());
        return Base64.getEncoder().encodeToString(hashBytes);
    }
    
    // Calculate SHA-3 hash
    public static String sha3_256(String input) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance(SHA_3_256);
        byte[] hashBytes = digest.digest(input.getBytes());
        return Base64.getEncoder().encodeToString(hashBytes);
    }
    
    // Salted hash (with random salt)
    public static String saltedHash(String password, byte[] salt) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance(SHA_256);
        digest.reset();
        digest.update(salt);
        byte[] hashBytes = digest.digest(password.getBytes());
        return Base64.getEncoder().encodeToString(hashBytes);
    }
    
    // Generate salt
    public static byte[] generateSalt() {
        byte[] salt = new byte[16];
        new SecureRandom().nextBytes(salt);
        return salt;
    }
    
    // PBKDF2 for password hashing
    public static String pbkdf2Hash(String password, byte[] salt, int iterations, int keyLength) 
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        
        PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, keyLength);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        byte[] hash = skf.generateSecret(spec).getEncoded();
        return Base64.getEncoder().encodeToString(hash);
    }
    
    // Verify password with PBKDF2
    public static boolean verifyPassword(String password, String storedHash, byte[] salt, int iterations) 
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        
        String newHash = pbkdf2Hash(password, salt, iterations, storedHash.length());
        return newHash.equals(storedHash);
    }
    
    // HMAC for message authentication
    public static String hmacSHA256(String data, String secretKey) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
        mac.init(secretKeySpec);
        byte[] hmacBytes = mac.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(hmacBytes);
    }
    
    // Test hash collisions
    public static void testHashCollisions() {
        try {
            System.out.println("=== Hash Collision Test ===");
            
            String[] testStrings = {
                "password123",
                "password124",  // Very similar
                "Password123",  // Case difference
                "pass word123", // With space
                "pa$$word123"   // Special character
            };
            
            System.out.println("SHA-256 Hashes:");
            for (String test : testStrings) {
                String hash = sha256(test);
                System.out.printf("%-15s: %s%n", test, hash);
            }
            
            System.out.println("\nSHA-3 Hashes:");
            for (String test : testStrings) {
                String hash = sha3_256(test);
                System.out.printf("%-15s: %s%n", test, hash);
            }
            
        } catch (Exception e) {
            System.err.println("Error in collision test: " + e.getMessage());
        }
    }
    
    // Password security demo
    public static void passwordSecurityDemo() {
        try {
            System.out.println("\n=== Password Security Demo ===");
            
            String password = "MySecurePassword123!";
            
            // 1. Simple hash (insecure)
            String simpleHash = sha256(password);
            System.out.println("Simple SHA-256: " + simpleHash);
            
            // 2. Salted hash
            byte[] salt = generateSalt();
            String saltedHashStr = saltedHash(password, salt);
            System.out.println("Salted Hash: " + saltedHashStr);
            System.out.println("Salt: " + Base64.getEncoder().encodeToString(salt));
            
            // 3. PBKDF2 (recommended)
            int iterations = 10000;
            int keyLength = 256;
            String pbkdf2HashStr = pbkdf2Hash(password, salt, iterations, keyLength);
            System.out.println("PBKDF2 Hash: " + pbkdf2HashStr);
            System.out.println("Iterations: " + iterations);
            
            // 4. Verification
            boolean isValid = verifyPassword(password, pbkdf2HashStr, salt, iterations);
            System.out.println("Password valid: " + isValid);
            
            // 5. Timing attack protection
            System.out.println("\nTiming Attack Protection Test:");
            testTimingAttackProtection();
            
        } catch (Exception e) {
            System.err.println("Error in password security: " + e.getMessage());
        }
    }
    
    // Timing attack protection demo
    public static void testTimingAttackProtection() {
        try {
            String correctPassword = "correctPassword123";
            String wrongPassword = "wrongPassword456";
            
            byte[] salt = generateSalt();
            String storedHash = pbkdf2Hash(correctPassword, salt, 10000, 256);
            
            // Timing tests
            long[] correctTimes = new long[10];
            long[] wrongTimes = new long[10];
            
            for (int i = 0; i < 10; i++) {
                // Correct password
                long start = System.nanoTime();
                verifyPassword(correctPassword, storedHash, salt, 10000);
                correctTimes[i] = System.nanoTime() - start;
                
                // Wrong password
                start = System.nanoTime();
                verifyPassword(wrongPassword, storedHash, salt, 10000);
                wrongTimes[i] = System.nanoTime() - start;
            }
            
            long avgCorrect = Arrays.stream(correctTimes).sum() / correctTimes.length;
            long avgWrong = Arrays.stream(wrongTimes).sum() / wrongTimes.length;
            
            System.out.printf("Correct password: %dms (average)%n", avgCorrect / 1_000_000);
            System.out.printf("Wrong password: %dms (average)%n", avgWrong / 1_000_000);
            System.out.printf("Timing difference: %.2f%%%n", 
                             Math.abs(avgCorrect - avgWrong) * 100.0 / Math.max(avgCorrect, avgWrong));
            
        } catch (Exception e) {
            System.err.println("Error in timing attack test: " + e.getMessage());
        }
    }
    
    // HMAC demo
    public static void hmacDemo() {
        try {
            System.out.println("\n=== HMAC Demo ===");
            
            String message = "This is a confidential message";
            String secretKey = "secretKey123";
            
            // Calculate HMAC
            String hmac = hmacSHA256(message, secretKey);
            System.out.println("Message: " + message);
            System.out.println("HMAC: " + hmac);
            
            // HMAC with wrong key
            String wrongKey = "wrongKey456";
            String wrongHmac = hmacSHA256(message, wrongKey);
            System.out.println("HMAC (wrong key): " + wrongHmac);
            
            // Verification
            boolean isValid = hmac.equals(hmacSHA256(message, secretKey));
            boolean isInvalid = !wrongHmac.equals(hmacSHA256(message, secretKey));
            
            System.out.println("HMAC valid: " + isValid);
            System.out.println("Wrong HMAC detected: " + isInvalid);
            
        } catch (Exception e) {
            System.err.println("Error in HMAC demo: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        testHashCollisions();
        passwordSecurityDemo();
        hmacDemo();
    }
}

4. SSL/TLS and Certificates

import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.security.*;
import java.security.cert.*;
import java.util.Base64;

public class SSLTLSDemo {
    
    // Create SSL context
    public static SSLContext createSSLContext() throws Exception {
        // Trust Manager (for server certificates)
        TrustManager[] trustManagers = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                
                public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                }
                
                public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                // In production: validate certificate
                    System.out.println("Server certificate validated");
                }
            }
        };
        
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagers, new SecureRandom());
        
        return sslContext;
    }
    
    // HTTPS request with SSL
    public static void makeHTTPSRequest(String urlString) {
        try {
            System.out.println("=== HTTPS Request Demo ===");
            
            URL url = new URL(urlString);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            
            // Set SSL context
            SSLContext sslContext = createSSLContext();
            connection.setSSLSocketFactory(sslContext.getSocketFactory());
            
            // Hostname verifier (for demo)
            connection.setHostnameVerifier((hostname, session) -> {
                System.out.println("Hostname: " + hostname);
                return true; // In production: proper hostname verification
            });
            
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(10000);
            
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            
            // Certificate information
            Certificate[] certs = connection.getServerCertificates();
            if (certs.length > 0 && certs[0] instanceof java.security.cert.X509Certificate) {
                java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) certs[0];
                System.out.println("Server Certificate:");
                System.out.println("  Subject: " + cert.getSubjectDN());
                System.out.println("  Issuer: " + cert.getIssuerDN());
                System.out.println("  Valid from: " + cert.getNotBefore());
                System.out.println("  Valid until: " + cert.getNotAfter());
                System.out.println("  Serial Number: " + cert.getSerialNumber());
            }
            
            // TLS version
            System.out.println("TLS Protocol: " + connection.getSSLSession().getProtocol());
            System.out.println("Cipher Suite: " + connection.getSSLSession().getCipherSuite());
            
            // Read response
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()))) {
                
                String line;
                StringBuilder response = new StringBuilder();
                
                while ((line = reader.readLine()) != null) {
                    response.append(line).append("\n");
                }
                
                System.out.println("Response (first 200 chars):");
                System.out.println(response.substring(0, Math.min(200, response.length())));
            }
            
        } catch (Exception e) {
            System.err.println("Error in HTTPS request: " + e.getMessage());
        }
    }
    
    // Generate self-signed certificate
    public static void generateSelfSignedCertificate() {
        try {
            System.out.println("\n=== Self-Signed Certificate Demo ===");
            
            // Generate KeyPair
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(2048);
            KeyPair keyPair = keyGen.generateKeyPair();
            
            // Create certificate (simplified)
            // In practice, you would use BouncyCastle or similar libraries
            System.out.println("KeyPair generated for self-signed certificate");
            System.out.println("Public Key: " + Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
            
        } catch (Exception e) {
            System.err.println("Error creating certificate: " + e.getMessage());
        }
    }
    
    // List cipher suites
    public static void listCipherSuites() {
        try {
            System.out.println("\n=== Supported Cipher Suites ===");
            
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, null, null);
            
            String[] cipherSuites = sslContext.getServerSocketFactory().getSupportedCipherSuites();
            
            System.out.println("Number of supported cipher suites: " + cipherSuites.length);
            System.out.println("\nRecommended Cipher Suites:");
            
            for (String suite : cipherSuites) {
                // Display only modern, secure cipher suites
                if (suite.contains("TLS_ECDHE") && suite.contains("GCM")) {
                    System.out.println("  " + suite);
                }
            }
            
        } catch (Exception e) {
            System.err.println("Error listing cipher suites: " + e.getMessage());
        }
    }
    
    // Analyze SSL handshake
    public static void analyzeSSLHandshake() {
        try {
            System.out.println("\n=== SSL Handshake Analysis ===");
            
            SSLContext sslContext = createSSLContext();
            
            // Custom SSL parameters
            SSLParameters sslParams = new SSLParameters();
            sslParams.setEndpointIdentificationAlgorithm("HTTPS");
            sslParams.setProtocols(new String[]{"TLSv1.3", "TLSv1.2"});
            
            // Secure cipher suites
            String[] secureSuites = {
                "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
                "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
                "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
            };
            sslParams.setCipherSuites(secureSuites);
            
            System.out.println("SSL Configuration:");
            System.out.println("  Protocols: " + String.join(", ", sslParams.getProtocols()));
            System.out.println("  Cipher Suites: " + sslParams.getCipherSuites().length + " configured");
            System.out.println("  Hostname Verification: " + sslParams.getEndpointIdentificationAlgorithm());
            
        } catch (Exception e) {
            System.err.println("Error in SSL analysis: " + e.getMessage());
        }
    }
    
    // Certificate chain validation
    public static void validateCertificateChain() {
        try {
            System.out.println("\n=== Certificate Chain Validation ===");
            
            // Example of certificate path validation
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            
            // In practice, you would load certificates from a file
            // Here we show only the concepts
            
            System.out.println("Certificate Path Validation Concepts:");
            System.out.println("1. Root CA Certificate");
            System.out.println("2. Intermediate CA Certificate(s)");
            System.out.println("3. End Entity Certificate");
            System.out.println("4. Certificate Revocation Check (CRL/OCSP)");
            System.out.println("5. Certificate Transparency Logs");
            
            // Trust manager configuration
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            
            // KeyStore for trusted certificates
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null); // Empty TrustStore
            
            // In production: load system TrustStore or add custom certificates
            // trustStore.load(new FileInputStream("truststore.jks"), "password".toCharArray());
            
            tmf.init(trustStore);
            
            TrustManager[] trustManagers = tmf.getTrustManagers();
            System.out.println("Trust Manager configured: " + trustManagers.length + " manager(s)");
            
        } catch (Exception e) {
            System.err.println("Error in certificate validation: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        // HTTPS request demo
        // makeHTTPSRequest("https://www.google.com");
        
        // Certificate demos
        generateSelfSignedCertificate();
        listCipherSuites();
        analyzeSSLHandshake();
        validateCertificateChain();
    }
}

Cryptography Algorithms Overview

Symmetric Algorithms

AlgorithmKey LengthBlock SizeUse CaseSecurity
AES128/192/256128 BitStandardSecure
DES5664DeprecatedInsecure
3DES16864LegacyWeak
Blowfish32-44864VariousSecure

Asymmetric Algorithms

AlgorithmKey LengthUse CaseSecurityPerformance
RSA1024-4096Signing/EncryptionSecureSlow
ECC160-521Signing/EncryptionSecureFast
DSA1024-3072SigningSecureSlow
ElGamal1024-4096EncryptionSecureSlow

Hash Algorithms

AlgorithmOutput LengthCollision ResistanceStatusUse Case
SHA-256256 BitSecureRecommendedGeneral Purpose
SHA-3224-512SecureModernGeneral Purpose
MD5128 BitBrokenDeprecatedChecksums
bcryptVariableSecureRecommendedPasswords

SSL/TLS Protocol Versions

VersionYearSecurityCipher SuitesRecommendation
SSL 2.01995InsecureDeprecatedDo Not Use
SSL 3.01996InsecureDeprecatedDo Not Use
TLS 1.01999WeakLimitedDo Not Use
TLS 1.12006OKLimitedDo Not Use
TLS 1.22008SecureModernRecommended
TLS 1.32018Very SecureModernBest Choice

Password Security Best Practices

Hashing Methods

// ❌ Insecure
String hash = md5(password);

// ⚠️ Better
String hash = sha256(password);

// ✅ Secure
String hash = pbkdf2(password, salt, 100000);

// ✅ Best
String hash = bcrypt(password);

Salting

// Generate salt
byte[] salt = generateSalt(); // 16+ bytes random

// Store salt (not secret)
String saltedHash = salt + ":" + hash(password, salt);

Key Derivation

// PBKDF2 parameters
int iterations = 100000; // At least 100,000
int keyLength = 256;     // 256 bit
int saltLength = 32;     // 32 bytes

String derivedKey = pbkdf2(password, salt, iterations, keyLength);

Digital Signatures Process

Signature Creation

  1. Calculate hash: hash = SHA256(data)
  2. Encrypt hash: signature = RSA_encrypt(hash, private_key)
  3. Append signature: data + signature

Signature Verification

  1. Extract signature: signature = extract(data_with_signature)
  2. Calculate hash: hash = SHA256(data)
  3. Decrypt signature: decrypted_hash = RSA_decrypt(signature, public_key)
  4. Compare: hash == decrypted_hash ?

Public Key Infrastructure (PKI)

Components

  • Root CA: Trusted root certificate authority
  • Intermediate CA: Intermediate certificate authorities
  • End Entity: Server/client certificates
  • CRL: Certificate Revocation List
  • OCSP: Online Certificate Status Protocol

Certificate Validation

// 1. Check certificate chain
// 2. Check expiration date
// 3. Check revocation (CRL/OCSP)
// 4. Check hostname
// 5. Verify signature

Security Best Practices

Implementation

// ✅ Secure configuration
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, trustManagers, null);

// ✅ Secure cipher suites
String[] secureSuites = {
    "TLS_AES_256_GCM_SHA384",
    "TLS_CHACHA20_POLY1305_SHA256",
    "TLS_AES_128_GCM_SHA256"
};

// ✅ Hostname verification
connection.setHostnameVerifier((hostname, session) -> {
    return hostname.equals(session.getPeerHost());
});

Common Mistakes to Avoid

// ❌ Wrong: Disabling TrustManager
TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() { /* accept all certificates */ }
};

// ✅ Right: Custom TrustManager with validation
TrustManager[] secureTrustManagers = new TrustManager[] {
    new X509TrustManager() {
        public void checkServerTrusted(X509Certificate[] chain, String authType) 
                throws CertificateException {
            // Custom validation logic
        }
    }
};

Advantages and Disadvantages

Benefits of Cryptography

  • Confidentiality: Protection from unauthorized access
  • Integrity: Detection of data tampering
  • Authenticity: Verification of identity
  • Non-Repudiation: Accountability
  • Compliance: Meeting security standards

Drawbacks

  • Complexity: Specialized knowledge required
  • Performance: Computationally intensive operations
  • Key Management: Managing keys is resource-heavy
  • Overhead: Additional infrastructure needed

Common Exam Questions

  1. What’s the difference between symmetric and asymmetric encryption? Symmetric encryption uses a single key for both directions, while asymmetric encryption uses public/private key pairs.

  2. Why are salted hashes important for passwords? Salts prevent rainbow table attacks and ensure unique hashes even when passwords are identical.

  3. Explain digital signatures. Digital signatures use hashing and asymmetric encryption to guarantee authenticity and integrity.

  4. What’s the purpose of SSL/TLS? SSL/TLS secures internet communication through encryption and authentication.

Key Resources

  1. https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html
  2. https://www.ietf.org/rfc/rfc5246.html (TLS 1.2)
  3. https://www.ietf.org/rfc/rfc8446.html (TLS 1.3)

Keine Bücher für Kategorie "cybersecurity" gefunden.

More Cybersecurity Articles

Cybersecurity and cryptography are critical for building secure software. The following articles help you master all aspects of IT security.

Linux Security

Back to Blog
Share:

Related Posts