OpenCSC

Java Spring Boot Library for CSC v2 Remote Digital Signing

Maven Central v1.0.1 Java 17+ Spring Boot 3.x Apache 2.0

Built on Open Standards

OpenCSC implements the Cloud Signature Consortium (CSC) API v2 specification, ensuring interoperability with any CSC-compliant remote signing service worldwide.

CSC API v2

The Cloud Signature Consortium (CSC) defines an open, interoperable API standard for remote electronic signatures. OpenCSC fully implements the CSC API v2 specification, including credentials management, authorization, and signature operations.

Cloud Signature Consortium

ETSI TS 119 432 V1.2.1

Compliant with the European Telecommunications Standards Institute (ETSI) specification for Protocols for remote digital signature creation. This standard defines the protocols for server-side signature creation, ensuring legal validity under eIDAS regulation.

ETSI TS 119 432 Specification
Open Standard Protocol
Interoperable with any CSC Server
eIDAS Regulation Compatible
PKCS#7 / CMS Compliant

Everything You Need for Remote Signing

A comprehensive, production-ready library with auto-configuration, resilience, and extensibility built in.

CSC API v2 Client

Full implementation of credentials/list, credentials/info, credentials/authorize, credentials/getChallenge, and signatures/signHash endpoints.

OAuth2 Token Management

Automatic client_credentials flow with proactive token refresh. Supports separate Authorization Servers (Keycloak, etc.).

Hash Signing

Sign single or batch hashes with automatic SCAL1/SCAL2 detection and SAD lifecycle management.

PDF Signing

Two-phase external signing via Apache PDFBox. Optional dependency — only activated when PDFBox is on the classpath.

CMS/PKCS#7 Containers

Bouncy Castle-powered CMS signature container builder with full certificate chain support.

Spring Boot Auto-Config

Zero boilerplate setup. Just add the dependency and configure properties. Conditional bean creation based on classpath and config.

Audit Events

Pluggable audit listener SPI. Receive events for token acquisition, credential authorization, signing, and errors.

Retry & Circuit Breaker

Optional Resilience4j integration with configurable retry policies and circuit breaker thresholds.

SCAL1/SCAL2 Handling

Automatic detection and handling of SCAL levels. Hashes are included in authorize requests only for SCAL2 credentials.

Clean, Layered Design

A facade pattern with clear separation of concerns. Each layer has a single responsibility and can be extended independently.

Your Application implements AuthDataProvider CscRemoteSigningFacade authorizeAndSignHash() • signPdf() OAuth2 Token Manager InMemoryTokenStore CSC API Client RestClient (HTTP) Audit Publisher CscAuditListener SPI Crypto / PDF CMS Builder • PdfHashExtractor CSC Resource Server CSC API v2 Endpoints Auth Server (optional, separate)

Up and Running in Minutes

Add the dependency, configure your CSC server details, and start signing.

Add Maven Dependency

xml
<dependency>
    <groupId>com.icebrown.opencsc</groupId>
    <artifactId>opencsc</artifactId>
    <version>1.0.1</version>
</dependency>

<!-- For PDF signing, also add: -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>3.0.3</version>
</dependency>

Configure application.yml

yaml
opencsc:
  base-url: "https://your-csc-server.com/csc/v2"
  oauth2:
    token-path: "/oauth2/token"
    client-id: "your-client-id"
    client-secret: "your-client-secret"
    scope: "service"
  pdf:
    enabled: true

Implement AuthDataProvider

Required when your credential uses explicit authorization (PIN/OTP):

java
@Bean
public AuthDataProvider authDataProvider() {
    return context -> {
        // context.getCredentialId()    — credential being authorized
        // context.getRequiredObjects() — auth types (PIN, OTP, etc.)
        // context.getCorrelationId()   — correlation ID for tracing
        return List.of(new AuthObject("PIN", "123456"));
    };
}

Use the Facade

java
@Autowired
CscRemoteSigningFacade cscFacade;

// List credentials
CredentialsListResponse creds = cscFacade.listCredentials(
    CredentialsListRequest.builder().authInfo(true).build());

// Sign hash (authorize + sign in one call)
SignHashResponse result = cscFacade.authorizeAndSignHash(
    "credentialId",
    List.of("base64EncodedHash"),
    "2.16.840.1.101.3.4.2.1",  // SHA-256
    "1.2.840.113549.1.1.11",   // SHA256withRSA
    "optional-client-data");

// Sign PDF
PdfSigningResult pdfResult = cscFacade.signPdf(
    PdfSigningRequest.builder()
        .pdfBytes(pdfBytes)
        .credentialID("credentialId")
        .reason("Contract signing")
        .build());
byte[] signedPdf = pdfResult.getSignedPdfBytes();

Fully Configurable

All properties are prefixed with opencsc.* and support Spring Boot's configuration binding.

PropertyDefaultDescription
base-url(required)CSC Resource Server base URL
auth-server-urlnullOAuth2 Authorization Server URL (falls back to base-url)
connect-timeout5sHTTP connection timeout
read-timeout30sHTTP read timeout
PropertyDefaultDescription
oauth2.token-path/oauth2/tokenToken endpoint path
oauth2.client-id(required)OAuth2 client ID
oauth2.client-secret(required)OAuth2 client secret
oauth2.scopenullOAuth2 scope
oauth2.token-expiry-skew30Seconds before expiry to trigger refresh
oauth2.refresh-check-interval30000Milliseconds between proactive refresh checks
PropertyDefaultDescription
credentials.list-path/credentials/listCredentials list endpoint
credentials.info-path/credentials/infoCredentials info endpoint
credentials.authorize-path/credentials/authorizeCredentials authorize endpoint
credentials.get-challenge-path/credentials/getChallengeGet challenge endpoint
signatures.sign-hash-path/signatures/signHashSign hash endpoint
PropertyDefaultDescription
retry.enabledtrueEnable retry on failed API calls
retry.max-attempts3Maximum retry attempts
retry.wait-duration500msWait between retries
circuit-breaker.enabledtrueEnable circuit breaker
circuit-breaker.failure-rate-threshold50Failure rate % to open circuit
PropertyDefaultDescription
pdf.enabledtrueEnable PDF signing (requires PDFBox)
pdf.default-hash-algorithm2.16.840...2.1Default hash algorithm OID (SHA-256)
pdf.signature-reserved-space-bytes32768Reserved bytes for CMS container in PDF

SPI Interfaces

Implement these interfaces and register as Spring beans to customize behavior.

AuthDataProvider

Supply PIN/OTP for explicit-mode credentials

java
@Bean
public AuthDataProvider authDataProvider() {
    return context -> {
        String credId = context.getCredentialId();
        List<String> required = context.getRequiredObjects();
        return List.of(
            new AuthObject("PIN", "123456")
        );
    };
}

CscAuditListener

Receive audit events for monitoring and logging

java
@Bean
public CscAuditListener auditListener() {
    return event -> switch (event) {
        case TokenAcquiredEvent e ->
            log.info("Token acquired");
        case HashSignedEvent e ->
            log.info("Signed {} hashes",
                e.hashCount());
        case PdfSignedEvent e ->
            log.info("PDF signed");
        case CscApiErrorEvent e ->
            log.error("Error: {}",
                e.errorMessage());
        default ->
            log.info("Event: {}", event);
    };
}