package com.cloudhandson.ddsbackoffice.service; import com.cloudhandson.ddsbackoffice.config.DdsProperties; import com.cloudhandson.ddsbackoffice.domain.DdsGrantPlan; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** Canonical, non-secret fingerprints used for publication/validation freshness checks. */ public final class DdsProtectionFingerprint { private DdsProtectionFingerprint() { } public static String service(DdsProperties properties) { return sha256("SERVICE|" + properties.vectorObject() + "|" + properties.token().dataRole() + "|DDS_DEMO_TOKEN_VECTOR_GRANT|ADMIN.CB_DDS_VECTOR_TAG_ALLOWED"); } public static String direct(DdsGrantPlan plan) { return sha256("DIRECT|" + plan.ddsObject() + "|" + plan.grantName() + "|" + plan.dataRole() + "|" + value(plan.predicate()) + "|" + value(plan.excludedColumns()) + "|" + plan.publishable()); } private static String value(String input) { return input == null ? "" : input.trim().replaceAll("\\s+", " "); } private static String sha256(String input) { try { byte[] bytes = MessageDigest.getInstance("SHA-256").digest(input.getBytes(StandardCharsets.UTF_8)); StringBuilder result = new StringBuilder(bytes.length * 2); for (byte value : bytes) { result.append(String.format("%02X", value)); } return result.toString(); } catch (NoSuchAlgorithmException exception) { throw new IllegalStateException("SHA-256을 사용할 수 없습니다.", exception); } } }