From 3877b8f466eaf58fd607515a63cf80a9e3e55eb8 Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Tue, 11 Feb 2025 11:35:10 +0100 Subject: [PATCH] TD-3: Create Player Service with Password Methods --- .../de/towerdefence/server/player/Player.java | 6 ++- .../server/player/PlayerService.java | 52 +++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/towerdefence/server/player/PlayerService.java diff --git a/src/main/java/de/towerdefence/server/player/Player.java b/src/main/java/de/towerdefence/server/player/Player.java index afabdc0..79a7fd3 100644 --- a/src/main/java/de/towerdefence/server/player/Player.java +++ b/src/main/java/de/towerdefence/server/player/Player.java @@ -15,6 +15,8 @@ import jakarta.persistence.*; @Entity @Table(name = "player") public class Player { + public static final int PASSWORD_SALT_BYTE_LENGTH = 16; + public static final int PASSWORD_HASH_BYTE_LENGTH = 64; @Id private Long id; @@ -24,10 +26,10 @@ public class Player { private String username; @NotNull - @Size(min = 64, max = 64) + @Size(min = PASSWORD_HASH_BYTE_LENGTH, max = PASSWORD_HASH_BYTE_LENGTH) private byte[] passwordHash; @NotNull - @Size(min = 16, max = 16) + @Size(min = PASSWORD_SALT_BYTE_LENGTH, max = PASSWORD_SALT_BYTE_LENGTH) private byte[] passwordSalt; } diff --git a/src/main/java/de/towerdefence/server/player/PlayerService.java b/src/main/java/de/towerdefence/server/player/PlayerService.java new file mode 100644 index 0000000..0cfc6d1 --- /dev/null +++ b/src/main/java/de/towerdefence/server/player/PlayerService.java @@ -0,0 +1,52 @@ +package de.towerdefence.server.player; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; + +@Component +public class PlayerService { + @Autowired + private PlayerRepository playerRepository; + + private final SecureRandom random; + + public PlayerService(PlayerRepository playerRepository) { + this.playerRepository = playerRepository; + this.random = new SecureRandom(); + } + + public boolean checkPassword(Player player, String password) throws NoSuchAlgorithmException { + return Arrays.equals( + hashPassword( + player.getPasswordSalt(), + password.getBytes(StandardCharsets.UTF_8) + ), + player.getPasswordHash() + ); + } + + public void setPassword(Player player, String password) throws NoSuchAlgorithmException { + byte[] salt = new byte[Player.PASSWORD_SALT_BYTE_LENGTH]; + this.random.nextBytes(salt); + + byte[] passwordHash = hashPassword( + salt, + password.getBytes(StandardCharsets.UTF_8) + ); + + player.setPasswordSalt(salt); + player.setPasswordHash(passwordHash); + } + + private static byte[] hashPassword(byte[] salt, byte[] password) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(salt); + return md.digest(password); + } +}