CryptoSignerService.java
package io.mersel.dss.signer.api.services.crypto;
import eu.europa.esig.dss.enumerations.DigestAlgorithm;
import eu.europa.esig.dss.enumerations.SignatureAlgorithm;
import eu.europa.esig.dss.model.SignatureValue;
import eu.europa.esig.dss.model.ToBeSigned;
import io.mersel.dss.signer.api.exceptions.SignatureException;
import io.mersel.dss.signer.api.models.SigningBackend;
import io.mersel.dss.signer.api.models.SigningMaterial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.security.Signature;
/**
* DSS'in 2-aşamalı imza akışında {@code SignatureValue} üreten düşük seviye
* servis. İki arka ucu da tek tip API'nin arkasına alır:
*
* <ul>
* <li><b>PFX (JCA)</b> → {@link Signature#getInstance(String)} üzerinden
* yazılım imza, mevcut davranış.</li>
* <li><b>HSM (PKCS#11 / IAIK)</b> →
* {@link SigningBackend#sign(byte[], SignatureAlgorithm)} ile token'da
* C_Sign çağrısı. SunPKCS11'in P11Key alias-mapping katmanına
* bağımlı değildir.</li>
* </ul>
*
* <p>Çağıran taraflar (XAdES / CAdES / WS-Security servisleri) sadece
* {@link #sign(ToBeSigned, SigningMaterial, DigestAlgorithm)} metodunu çağırır;
* arka uç seçimi {@link SigningMaterial} içindeki {@link SigningBackend}
* kontratına delege edilir.</p>
*/
@Service
public class CryptoSignerService {
private static final Logger LOGGER = LoggerFactory.getLogger(CryptoSignerService.class);
private final SignatureAlgorithmResolverService algorithmResolver;
public CryptoSignerService(SignatureAlgorithmResolverService algorithmResolver) {
this.algorithmResolver = algorithmResolver;
}
/**
* Birleşik imzalama girişi: imzalanacak algoritmayı sertifikadan çözer,
* sonra gerçek imza operasyonunu material içindeki arka uç kontratına
* delege eder.
*
* @param dataToSign DSS'in {@code getDataToSign()} çıktısı
* @param material imzalama materyali (PFX veya HSM)
* @param digestAlgorithm sertifikaya göre çözümlenmiş digest algoritması
* @return DSS {@code signDocument(signatureValue)}'a verilecek imza değeri
*/
public SignatureValue sign(ToBeSigned dataToSign,
SigningMaterial material,
DigestAlgorithm digestAlgorithm) {
try {
SignatureAlgorithm signatureAlgorithm =
algorithmResolver.determineSignatureAlgorithm(
material.getSigningCertificate(), digestAlgorithm);
byte[] signatureBytes = material.sign(dataToSign.getBytes(), signatureAlgorithm);
LOGGER.debug("İmza başarıyla oluşturuldu. Backend: {}, Algoritma: {}",
material.getBackendName(), signatureAlgorithm);
return new SignatureValue(signatureAlgorithm, signatureBytes);
} catch (SignatureException e) {
throw e;
} catch (Exception e) {
throw new SignatureException("İmza oluşturulamadı", e);
}
}
}