Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

627 encryptionbuilder aus wls common entfernen und fix config key für crypto.key #635

Merged
merged 8 commits into from
Dec 13, 2024

Conversation

MrSebastian
Copy link
Member

@MrSebastian MrSebastian commented Dec 11, 2024

Beschreibung:

  • EncryptionBuilder aus wls-common entfernt und in Crypto-Service integriert. Eine separate Klasse halte ich nicht für sinnvoll da der Crypto-Service alle relevanten Funktion bereits anbietet.
  • dabei Config-Wert für für den Key entsprechend doku verwendet
  • Wert in der pom passend zu den anderen Testdaten angepasst und aus unbekannten Gründne funktioniert der alte Wert nicht mehr

Definition of Done (DoD):

Backend

  • Doku aktualisiert - kein Update erforderlich: neue Konfig-Key war bereits dokumentiert
  • Swagger-API vollständig - keine API-Änderungen
  • Unit-Tests gepflegt - weitgehend von wls-common übernommen
  • Integrationstests gepflegt - angepasst um zu sehen dass sich mit einem konfiguriertem Crypto-Key en- und decrypten lässt

Referenzen1:

Verwandt mit Issue #

Closes #627

Summary by CodeRabbit

  • New Features

    • Introduced a new configuration section for cryptographic keys in application settings.
    • Added a new integration test for CryptoService to validate encryption and decryption processes.
    • Implemented comprehensive unit tests for CryptoService focusing on encryption and decryption functionalities.
  • Bug Fixes

    • Updated configuration properties to align with new cryptographic key management.
  • Bug Fixes

    • Removed outdated integration and unit tests related to the EncryptionBuilder.
  • Chores

    • Restructured packages for better organization of encryption-related classes.

Footnotes

  1. Nicht zutreffende Referenzen vor dem Speichern entfernen

@MrSebastian MrSebastian self-assigned this Dec 11, 2024
@MrSebastian MrSebastian linked an issue Dec 11, 2024 that may be closed by this pull request
1 task
@MrSebastian MrSebastian marked this pull request as draft December 11, 2024 14:36
@MrSebastian
Copy link
Member Author

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Dec 11, 2024

Walkthrough

The pull request involves a restructuring of the wls-auth-service package, specifically moving the AESEncryptionConfiguration and EncryptionBuilder classes to a new package. The configuration property for the AES encryption key has been updated to reflect this change. The EncryptionConfiguration class has been removed, and the CryptoService class has been modified to use Cipher instances directly instead of EncryptionBuilder. Additionally, new test classes have been introduced, and existing tests have been updated to align with the new configuration.

Changes

File Change Summary
.../authservice/configuration/AESEncryptionConfiguration.java Package changed; updated @Value property for AES key from ${app.crypto.key} to ${service.config.crypto.key}.
.../authservice/configuration/EncryptionConfiguration.java Class and method removed.
.../authservice/exception/ExceptionConstants.java Added new constant CRYPTO_EXCEPTION_CODE with value "399".
.../authservice/security/EncryptionBuilder.java Class moved to a new package; no internal changes.
.../authservice/service/CryptoService.java Constructor updated to inject Cipher instances; new private methods encryptValue and decryptValue added.
.../resources/application-local.yml New configuration section under service.config added; serviceauth section removed.
.../resources/application-test.yml New configuration section under service.config added.
.../test/domain/UserRepositoryImplIntegrationTest.java Updated test properties to reflect new encryption key.
.../test/rest/WahllokalBenutzerControllerIntegrationTest.java Removed obsolete encryption key property from test configuration.
.../test/service/CryptoServiceIntegrationTest.java New integration test class for CryptoService added.
.../test/service/CryptoServiceTest.java New unit tests for CryptoService added, covering various scenarios.
.../common/security/EncryptionBuilderIntegrationTest.java Class removed.
.../common/security/EncryptionBuilderTest.java Class removed.

Assessment against linked issues

Objective Addressed Explanation
Remove EncryptionBuilder from WLS-Common as it is only used in Auth-Service (#627)
Reduce complexity by eliminating unnecessary initialization of EncryptionBuilder (#627)

Possibly related PRs

  • #555 update test names #602: Involves renaming test methods in the NfcConverterTest class, which relates to overall naming conventions in the wls-auth-service project.

Suggested labels

service-vorfaelleundvorkommnisse

Poem

🐰 In the code where secrets lie,
A bunny hops, oh my, oh my!
With keys that change and classes shift,
The service grows, a lovely gift.
Encryption's dance, both swift and sly,
In the auth-service, we now fly!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Outside diff range and nitpick comments (9)
wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoServiceTest.java (5)

29-29: Consider using a more realistic encryption prefix

The current prefix "encryptionPrefix" is generic. Consider using a more realistic prefix that matches your production environment (e.g., "{AES}") to ensure tests reflect real-world scenarios.


31-38: Add constructor validation tests

The test suite is missing validation for the CryptoService constructor. Consider adding tests to verify:

  • Proper initialization with valid Cipher instances
  • Handling of null Cipher instances
  • Verification of Cipher transformation/mode

45-58: Add edge cases to IsEncrypted tests

The current test coverage for isEncrypted() should be expanded to include:

  • Null input handling
  • Empty string input
  • Case sensitivity verification (if applicable)

Example test cases to add:

@Test
void should_handleNullValue() {
    Assertions.assertThat(unitUnderTest.isEncrypted(null)).isFalse();
}

@Test
void should_handleEmptyString() {
    Assertions.assertThat(unitUnderTest.isEncrypted("")).isFalse();
}

63-74: Add cipher initialization verification

The encryption tests should verify that the cipher is properly initialized for encryption mode. Consider adding verification:

@Test
void should_initializeCipherInEncryptMode() throws Exception {
    val valueToEncrypt = "test";
    unitUnderTest.encrypt(valueToEncrypt);
    
    Mockito.verify(cipher).init(Cipher.ENCRYPT_MODE, any(Key.class));
}

115-165: Add tests for malformed input

The decrypt tests should include validation for:

  • Malformed Base64 input
  • Invalid padding
  • Incomplete encrypted data

Example test:

@Test
void should_handleMalformedBase64Input() {
    val malformedInput = ENCRYPTION_PREFIX + "not-base64!@#";
    
    Assertions.assertThatThrownBy(() -> unitUnderTest.decrypt(malformedInput))
        .isInstanceOf(TechnischeWlsException.class)
        .hasMessageContaining("malformed input");
}
wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/security/EncryptionBuilder.java (2)

Line range hint 41-43: Security: Remove sensitive data from error logs.

The error logging statements include the actual values being encrypted/decrypted. This could expose sensitive information in log files.

Apply this diff to remove sensitive data from logs:

-                log.error("Unable to decrypt the given value <" + value + "> as of an " + e.getClass().getSimpleName() + ". Using direct object reference!", e);
+                log.error("Unable to decrypt value due to {}. Using direct object reference!", e.getClass().getSimpleName(), e);
-                log.error("Unable to encrypt the given value <" + value + "> as of an " + e.getClass().getSimpleName() + ". Using direct object reference!", e);
+                log.error("Unable to encrypt value due to {}. Using direct object reference!", e.getClass().getSimpleName(), e);

Also applies to: 49-50


Line range hint 33-54: Improve robustness of encryption/decryption methods.

The methods should:

  1. Use explicit character encoding
  2. Validate Base64 input
  3. Consider adding input size limits

Apply this diff to improve the implementation:

     public String decryptValue(String value) {
         if (value != null && !value.isEmpty()) {
             try {
-                val decode = Base64.getUrlDecoder().decode(value.getBytes());
+                val decode = Base64.getUrlDecoder().decode(value.getBytes(StandardCharsets.UTF_8));
                 val finalized = decryptionCipher.doFinal(decode);
-                return new String(finalized);
+                return new String(finalized, StandardCharsets.UTF_8);
             } catch (IllegalBlockSizeException | BadPaddingException e) {
                 log.error("Unable to decrypt value due to {}. Using direct object reference!", e.getClass().getSimpleName(), e);
                 throw TechnischeWlsException.withCode(technischeExceptionKonstante).inService(formatter.getId())
                         .buildWithMessage("Problem bei Referenzierung/Dereferenzierung von Objekt-Referenzen");
+            } catch (IllegalArgumentException e) {
+                log.error("Invalid Base64 input", e);
+                throw TechnischeWlsException.withCode(technischeExceptionKonstante).inService(formatter.getId())
+                        .buildWithMessage("Ungültiges Format der verschlüsselten Daten");
             }
         }
         return value;
     }
 
     public String encryptValue(String value) {
         if (value != null && !value.isEmpty()) {
             try {
-                val finalized = encryptionCipher.doFinal(value.getBytes());
+                // Add size validation to prevent excessive memory usage
+                if (value.length() > 1000) {
+                    throw new IllegalArgumentException("Input too large");
+                }
+                val finalized = encryptionCipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
                 value = Base64.getUrlEncoder().encodeToString(finalized);
             } catch (IllegalBlockSizeException | BadPaddingException e) {
                 log.error("Unable to encrypt value due to {}. Using direct object reference!", e.getClass().getSimpleName(), e);
                 throw TechnischeWlsException.withCode(technischeExceptionKonstante).inService(formatter.getId())
                         .buildWithMessage("Problem bei Referenzierung/Dereferenzierung von Objekt-Referenzen");
+            } catch (IllegalArgumentException e) {
+                log.error("Input validation failed", e);
+                throw TechnischeWlsException.withCode(technischeExceptionKonstante).inService(formatter.getId())
+                        .buildWithMessage("Eingabedaten zu groß");
             }
         }
         return value;
     }

Don't forget to add the import:

import java.nio.charset.StandardCharsets;
wls-auth-service/src/main/resources/application-local.yml (1)

12-12: Add a newline at the end of the file

The file does not end with a newline character, which is recommended for POSIX compliance and to prevent potential issues with some tools.

Apply this diff to add the newline:

-    seed: change_me
+    seed: change_me
🧰 Tools
🪛 yamllint (1.35.1)

[error] 12-12: no new line character at the end of file

(new-line-at-end-of-file)

wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/configuration/AESEncryptionConfiguration.java (1)

Line range hint 18-24: Security: Update cipher initialization with secure mode

The current implementation uses ECB mode by default, which is not recommended for secure operations.

Update the cipher initialization:

-        val secret = new SecretKeySpec(key.getBytes(), 0, 16, AES);
-        val encryptCipher = Cipher.getInstance(AES);
+        val secret = new SecretKeySpec(deriveKey(), AES);
+        val encryptCipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
+        val iv = new byte[12]; // GCM requires 12 bytes IV
+        SecureRandom.getInstanceStrong().nextBytes(iv);
+        encryptCipher.init(Cipher.ENCRYPT_MODE, secret, new GCMParameterSpec(128, iv));

Similar changes should be applied to the decryption cipher.

Also applies to: 26-32

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 91f4bf2 and 872b17e.

📒 Files selected for processing (13)
  • wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/configuration/AESEncryptionConfiguration.java (2 hunks)
  • wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/configuration/EncryptionConfiguration.java (0 hunks)
  • wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/exception/ExceptionConstants.java (1 hunks)
  • wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/security/EncryptionBuilder.java (1 hunks)
  • wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoService.java (1 hunks)
  • wls-auth-service/src/main/resources/application-local.yml (1 hunks)
  • wls-auth-service/src/main/resources/application-test.yml (1 hunks)
  • wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/domain/UserRepositoryImplIntegrationTest.java (1 hunks)
  • wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/rest/WahllokalBenutzerControllerIntegrationTest.java (1 hunks)
  • wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoServiceIntegrationTest.java (1 hunks)
  • wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoServiceTest.java (1 hunks)
  • wls-common/security/src/test/java/de/muenchen/oss/wahllokalsystem/wls/common/security/EncryptionBuilderIntegrationTest.java (0 hunks)
  • wls-common/security/src/test/java/de/muenchen/oss/wahllokalsystem/wls/common/security/EncryptionBuilderTest.java (0 hunks)
💤 Files with no reviewable changes (3)
  • wls-common/security/src/test/java/de/muenchen/oss/wahllokalsystem/wls/common/security/EncryptionBuilderIntegrationTest.java
  • wls-common/security/src/test/java/de/muenchen/oss/wahllokalsystem/wls/common/security/EncryptionBuilderTest.java
  • wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/configuration/EncryptionConfiguration.java
🧰 Additional context used
🪛 yamllint (1.35.1)
wls-auth-service/src/main/resources/application-local.yml

[error] 12-12: no new line character at the end of file

(new-line-at-end-of-file)

🪛 Gitleaks (8.21.2)
wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoServiceIntegrationTest.java

13-13: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (9)
wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/rest/WahllokalBenutzerControllerIntegrationTest.java (3)

Line range hint 92-93: LGTM: Encryption handling maintained correctly

The test correctly uses CryptoService for username decryption and verification, maintaining the encryption functionality while adapting to the architectural changes (removal of EncryptionBuilder).

Also applies to: 94-95


Line range hint 63-175: LGTM: Comprehensive test coverage maintained

The test suite maintains thorough coverage of all operations while properly handling encryption:

  • Create/Export: Verifies both persistence and proper encryption/decryption
  • Delete: Ensures proper cleanup with wahltagID scoping
  • Export: Validates correct retrieval and filtering

36-36: Verify crypto key configuration for tests

The removal of service.config.crypto.key property from the test configuration suggests that this value is now being provided through a different mechanism (likely application-test.yml). Let's verify this to ensure test stability.

wls-auth-service/src/test/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoServiceTest.java (1)

1-166: Overall test implementation looks solid

The test suite provides good coverage of the CryptoService functionality and aligns well with the PR objectives of moving encryption handling to the Crypto-Service. The structure is clean, and the tests are well-organized.

wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/security/EncryptionBuilder.java (3)

4-4: Package relocation aligns with PR objectives.

The move from wls.common.security to authservice.security successfully fulfills the goal of removing the EncryptionBuilder from WLS-Common.


Line range hint 26-31: Well-structured dependency injection.

Good practices observed:

  • Constructor injection
  • Proper use of @qualifier to distinguish between Cipher instances
  • Final fields ensuring thread-safety

Line range hint 16-17: Verify complete migration to CryptoService.

Since this class is being moved from WLS-Common to Auth-Service as part of integrating with CryptoService, let's verify the integration is complete.

✅ Verification successful

Let me gather more information about the implementation details to verify the complete migration.


Let me try a different approach to get the implementation details.


Migration to CryptoService is complete and properly implemented

The CryptoService has successfully incorporated all functionality from EncryptionBuilder with the following improvements:

  • Maintains the same core encryption/decryption logic using the same dependencies
  • Adds prefix handling functionality with encryptedPrefix and isEncrypted() method
  • Uses consistent error handling with dedicated exception constants
  • Implements better logging with @slf4j annotation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that CryptoService implements all functionality from EncryptionBuilder

# Check for any remaining references to EncryptionBuilder in the codebase
echo "Checking for remaining EncryptionBuilder references..."
rg "EncryptionBuilder" --type java

# Check CryptoService implementation
echo "Checking CryptoService implementation..."
rg "class CryptoService" --type java -A 10

Length of output: 5290


Script:

#!/bin/bash
# Get full implementation of both classes to compare functionality
echo "EncryptionBuilder implementation:"
ast-grep --pattern 'class EncryptionBuilder {
  $$$
}'

echo -e "\nCryptoService implementation:"
ast-grep --pattern 'class CryptoService {
  $$$
}'

# Check for any usages of EncryptionBuilder in the codebase
echo -e "\nChecking EncryptionBuilder usages:"
rg -B 2 -A 2 "new EncryptionBuilder" --type java

Length of output: 397


Script:

#!/bin/bash
# Get the full content of both files
echo "EncryptionBuilder implementation:"
cat wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/security/EncryptionBuilder.java

echo -e "\nCryptoService implementation:"
cat wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/service/CryptoService.java

# Search for any autowired/injected usage of EncryptionBuilder
echo -e "\nChecking for EncryptionBuilder dependencies:"
rg "@Autowired.*EncryptionBuilder|@Inject.*EncryptionBuilder" --type java

Length of output: 6919

wls-auth-service/src/main/resources/application-test.yml (1)

20-21: LGTM

The addition of the crypto.key configuration in the test environment is appropriate and aligns with the application's requirements.

wls-auth-service/src/main/java/de/muenchen/oss/wahllokalsystem/authservice/exception/ExceptionConstants.java (1)

10-10: LGTM

The new exception code CRYPTO_EXCEPTION_CODE is appropriately defined and enhances error handling consistency.

@MrSebastian MrSebastian merged commit ad29c28 into dev Dec 13, 2024
6 checks passed
@MrSebastian MrSebastian deleted the 627-encryptionbuilder-aus-wls-common-entfernen branch December 13, 2024 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

EncryptionBuilder aus WLS-Common entfernen
2 participants