feat: record DDS protection evidence

This commit is contained in:
devmrko
2026-06-30 20:56:52 +09:00
parent f162851bc6
commit 22a7eda219
17 changed files with 985 additions and 18 deletions

View File

@@ -0,0 +1,41 @@
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);
}
}
}