package cz.trask.migration.util; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.Map; import javax.crypto.Cipher; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.log4j.Log4j2; @Log4j2 public class CredentialsDecoder { public static String decodeCredentials(String credentials, String pkFile) { if (credentials == null || credentials.isEmpty()) { log.warn("No credentials provided to decode."); return null; } try { String decodedJson = new String(Base64.getDecoder().decode(credentials)); log.debug("Decoded JSON: {}", decodedJson); ObjectMapper mapper = new ObjectMapper(); Map jsonMap = mapper.readValue(decodedJson, Map.class); String cipherBase64 = jsonMap.get("c"); String transformation = jsonMap.get("t"); log.debug("Used algorithm: {}", transformation); String privateKeyPEM = new String(Files.readAllBytes(Paths.get(pkFile))) .replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s+", ""); byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyPEM); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); byte[] encryptedBytes = Base64.getDecoder().decode(cipherBase64); Cipher cipher = Cipher.getInstance(transformation); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes, "UTF-8"); log.debug("Decoded credential: {}", decryptedText); return decryptedText; } catch (Exception e) { log.error("Error decoding credentials: ", e); return null; } } }