πŸ” RS-Imzo API Key Integration Guide

This document explains how to integrate your system with RS-Imzo using API Key authentication for signing and verifying electronic documents.


🧩 Overview

The RS-Imzo integration allows third-party systems to:

  • Register and receive an API Key and Public Key
  • Verify their domain registration using the Public Key (frontend)
  • Use the API Key (backend) for PKCS#7 signature verification, merging or authentication

🧱 Integration Flow

  1. Login to the RS-Imzo Cabinet
    • Go to your organization’s cabinet in the RS-Imzo system.
    • Navigate to API Integration.
    • Register for API integration.
  2. Obtain Keys
    • After registration, you will receive:
      • Public Key β€” used on the frontend for domain verification.
      • API Key β€” used on the backend for signature operations.

βš™οΈ Backend Integration

Once the frontend retrieves the PKCS#7 signature, the backend uses the RS-Imzo APIs that enables applications to perform signature verification, signature merging, and authentication using PKCS#7 standard signatures.

Base URL

$base_url=https://api.rs-imzo.uz/api/v1/backend

βš™οΈ API Endpoints

MethodEndpointDescription
POST/pkcs7/verifyVerify PKCS#7 signature
POST/pkcs7/mergeMerge two PKCS#7's into one
POST/authAuthenticate and extract user's data

🧩 Headers

All endpoints require the following headers:

HeaderDescription
X-API-KEYYour organization’s unique API key
Content-TypeAlways application/x-www-form-urlencoded

Example:

X-API-KEY: your-api-key
Content-Type: application/x-www-form-urlencoded

🧾 Request Parameters:

FieldTypeDescription
pkcs7stringBase64-encoded PKCS#7 signature
detachedDatastring(Optional) Detached data, if available

🧾 Info for response objects:

FieldTypeDescription
datastringThe data that is signed by user (always base64)
detachedbooleanIt is an indicator that the pkcs7 is used as attached or detached
signersList<Signer>Signers inside the PKCS#7
certificateObjectIt is an object the defines info of user, the issuer, the validness of the signature and etc..
digeststringIt is a signed content in md5 format
signed_timedateThe time that the date signed on
verifiedbooleanThe indication of the signature is verified or not
issuerObjectThis is an object that defines the issuer of a signature
serialstringIt is unique idetnifier for user's signature given by issuer
subjectObjectThe object that defines user's uid, country, personal info
validityObjectThe object the determines the activation and expiration time for signature
CstringThis determines the country of subject or issuer
CNstringFull name of signature owner
OstringOrganization name
1.3.6.1.4.1.64375.1.2stringPINPP of signature owner
1.3.6.1.4.1.64375.1.1stringTIN of organization
not_afterdateDetermines the validness of a signature until this time
not_beforedateDetermines the validness of a signature before this time

Curl examples for API requests and response examples:

1. Verify PKCS#7 Signature

To verify a PKCS#7 signature:

curl -X POST "${base_url}/pkcs7/verify" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "X-API-Key: AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe" \
  -d "pkcs7=MIICkQYJKoZIhvcNAQcCoIICgjCCAoYCAQExDzANBglghkgB..." \
  -d "detachedData=''"

This method checks whether the PKCS#7 is valid and if so it gives the parsed pkcs7 in object formatted as ParsePkcs7.

Response Example

{
  "data": "nrtwegwjwenw",
  "detached": true,
  "signers": [
    {
      "certificate": {
        "extensions": [
          {
            "oid": "",
            "value": ""
          }
        ],
        "inbase64": "",
        "issuer": {
          "C": "",
          "CN": "",
          "O": "",
          "L": ""
        },
        "serial": "",
        "signature_algorithm": "",
        "subject": {
          "1.3.6.1.4.1.64375.1.2": "",
          "1.3.6.1.4.1.64375.1.1": "",
          "C": "",
          "L": "",
          "CN": "",
          "O": "",
          "documentIdentifier": ""
        },
        "subject_public_key_info": {
          "algorithm": "",
          "public_key": ""
        },
        "validity": {
          "not_after": "",
          "not_before": ""
        },
        "version": 1
      },
      "digest": "3369cd520c8e556502b9bc0ac34ca69cafee96f2f4a8371a63d4dd7d3a458d05",
      "signed_time": "2022-09-27 11:17:53",
      "verified": true
    }
  ]
}

2. Merge PKCS#7 Signatures

To merge 2 PKCS#7 signatures:

curl -X POST "${base_url}/pkcs7/merge" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "X-API-Key: AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe" \
  -d "pkcs7=MIICkQYJKoZIhvcNAQcCoIICgjCCAoYCAQExDzANBglgh...|MIIFaAYJKoZIhvcNAQcCoIIFWTCCBVUCAQExDz..." \
  -d "detachedData=''"

This method merges 2 pkcs7 signatures and gives the result object formatted as String.

Response Example

MIICkQYJKoZIhvcNAQcCoIICgjCCAoYC...base64-encoded merged data...

3. Auth PKCS#7 Signature

To authenticate a user by their PKCS#7 signature:

curl -X POST "${base_url}/auth" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "X-API-Key: AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe" \
  -d "pkcs7=MIICkQYJKoZIhvcNAQcCoIICgjCCAoYCAQExDzANBglghkgB..." \
  -d "detachedData=''"

This method checks whether the PKCS#7 is valid and if so it gives the parsed pkcs7 in object formatted as ParsePkcs7.

Response Example

{
  "data": "nrtwegwjwenw",
  "detached": true,
  "signers": [
    {
      "certificate": {
        "extensions": [
          {
            "oid": "",
            "value": ""
          }
        ],
        "inbase64": "",
        "issuer": {
          "C": "",
          "CN": "",
          "O": "",
          "L": ""
        },
        "serial": "",
        "signature_algorithm": "",
        "subject": {
          "1.3.6.1.4.1.64375.1.2": "",
          "1.3.6.1.4.1.64375.1.1": "",
          "C": "",
          "L": "",
          "CN": "",
          "O": "",
          "documentIdentifier": ""
        },
        "subject_public_key_info": {
          "algorithm": "",
          "public_key": ""
        },
        "validity": {
          "not_after": "",
          "not_before": ""
        },
        "version": 1
      },
      "digest": "3369cd520c8e556502b9bc0ac34ca69cafee96f2f4a8371a63d4dd7d3a458d05",
      "signed_time": "2022-09-27 11:17:53",
      "verified": true
    }
  ]
}

πŸ’» Java Example for Client

Below is an example of how to use RS-Imzo’s API endpoints in Java style using Spring’s RestTemplate.

@Service
@Slf4j
public class RSImzoClient {

    private final RestTemplate restTemplate;

    public RSImzoClient(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    private static final String BASE_URL = "https://api.rs-imzo.uz/api/v1/backend";
    private static final String API_KEY = "your-api-key";

    private static final Gson gson = new GsonBuilder()
            .registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, type, context) ->
                    new Date(json.getAsJsonPrimitive().getAsLong() * 1000))
            .setDateFormat("yyyy-MM-dd HH:mm:ss")
            .setFieldNamingStrategy(FieldNamingPolicy.IDENTITY)
            .create();

    private String post(String url, Pkcs7Req req) {
        try {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set("X-API-Key", API_KEY);
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            String body = "pkcs7=" + req.getPkcs7() + "&detachedData=" + req.getDetachedData();
            HttpEntity<String> entity = new HttpEntity<>(body, httpHeaders);

            ResponseEntity<String> response = restTemplate.exchange(
                    BASE_URL + url,
                    HttpMethod.POST,
                    entity,
                    String.class
            );

            if (response.getStatusCode().isError()) {
                throw new RuntimeException("Error: " + response.getBody());
            }

            return response.getBody();
        } catch (Exception e) {
            log.error("Error calling {}: {}", url, e.getMessage(), e);
            throw new RuntimeException("Error during API call: " + e.getMessage(), e);
        }
    }

    public ParsePkcs7 verifyPkcs7(Pkcs7Req req) {
        String response = post("/pkcs7/verify", req);
        return gson.fromJson(response, ParsePkcs7.class);
    }

    public String mergePkcs7(Pkcs7Req req) {
        return post("/pkcs7/merge", req);
    }

    public ParsePkcs7 auth(Pkcs7Req req) {
        String response = post("/auth", req);
        return gson.fromJson(response, ParsePkcs7.class);
    }
}

πŸ“œ Example Headers Map

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("X-API-Key", API_KEY);
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

πŸ“š Request/Response Object Examples in Java

Pkcs7Req:

@Data
public class Pkcs7Req {
    @SerializedName("pkcs7")
    private String pkcs7;
    @SerializedName("detachedData")
    private String detachedData;
}

ParsePkcs7:

@Data
public class ParsePkcs7 {
    @SerializedName("data")
    private String data;
    @SerializedName("detached")
    private Boolean detached;
    @SerializedName("signers")
    private List<Signer> signers;
}

Signer:

@Data
public class Signer {
    @SerializedName("certificate")
    private Certificate certificate;
    @SerializedName("digest")
    private String digest;
    @SerializedName("signed_time")
    private Date signedTime;
    @SerializedName("verified")
    private Boolean verified;
}

Certificate:

@Data
public class Certificate {
    @SerializedName("extensions")
    private List<Extension> extensions;
    @SerializedName("inbase64")
    private String inbase64;
    @SerializedName("issuer")
    private Issuer issuer;
    @SerializedName("serial")
    private String serial;
    @SerializedName("signature_algorithm")
    private String signatureAlgorithm;
    @SerializedName("subject")
    private Subject subject;
    @SerializedName("subject_public_key_info")
    private SubjectPublicKeyInfo subjectPublicKeyInfo;
    @SerializedName("validity")
    private Validity validity;
    @SerializedName("version")
    private Integer version;
}

Extension:

@Data
public class Extension {
    @SerializedName("oid")
    private String oid;
    @SerializedName("value")
    private Object value;
}

Validity:

@Data
public class Validity {
    @SerializedName("not_after")
    private Date activationDate;
    @SerializedName("not_before")
    private Date expirationDate;
}

SubjectPublicKeyInfo:

@Data
public class SubjectPublicKeyInfo {
    @SerializedName("algorithm")
    private String algorithm;
    @SerializedName("public_key")
    private String publicKey;
}

Issuer:

@Data
public class Issuer {
    @SerializedName("C")
    private String country;
    @SerializedName("CN")
    private String companyRoot;
    @SerializedName("O")
    private String companyName;
    @SerializedName("L")
    private String address;
}

Subject:

@Data
public class Subject {
    @SerializedName("1.3.6.1.4.1.64375.1.2")
    private String pinp;
    @SerializedName("1.3.6.1.4.1.64375.1.1")
    private String tin;
    @SerializedName("C")
    private String country;
    @SerializedName("L")
    private String address;
    @SerializedName("CN")
    private String fullName;
    @SerializedName("O")
    private String organizationName;
    @SerializedName("documentIdentifier")
    private String documentIdentifier;
}

🧠 API request notes

  • Use API Key for authentication β€” no middleware or session handling is required.
  • You can call any of the three APIs (verify, merge, auth) independently.
  • All requests must be made over HTTPS.
  • Recommended timeout: 10 seconds.

Example Calls in Java:

🧾 1. Call for verify

Pkcs7Req req = new Pkcs7Req();
req.setPkcs7("MIIBase64Example...");
req.setDetachedData("optional-data");

ParsePkcs7 result = rsImzoClient.verifyPkcs7(req);

🧾 2. Call for merge

String oldPkcs7 = "MIICkQYJKoZIhvcNAQcCoIICgjCCAoYCAQExDz...";
String newPkcs7 = "MIIFaAYJKoZIhvcNAQcCoIIFWTCCBVUCAQExDz...";

Pkcs7Req req = new Pkcs7Req();
req.setPkcs7(oldPkcs7 + "|" + newPkcs7);
req.setDetachedData("optional-data");

String mergedPkcs7 = rsImzoClient.mergePkcs7(req, headers);

🧾 3. Call for auth

Pkcs7Req req = new Pkcs7Req();
req.setPkcs7("MIIBase64Example...");
req.setDetachedData("optional-data");

ParsePkcs7 result = rsImzoClient.auth(req);

🧩 Integration Checklist

  1. βœ… Obtain your X-API-KEY from RS-Imzo admin.
  2. βœ… Implement the RSImzoClient service.
  3. βœ… Test verify, merge, and auth APIs in your application.
  4. βœ… Log all failed verification attempts for auditing.

🧠 Summary

ComponentPurposeAuthentication
FrontendValidates domain registrationAuthorization: Bearer <PUBLIC_KEY>
BackendVerifies, merges or authenticates PKCS#7 signaturesX-API-Key: <API_KEY>

βœ… Example Flow Diagram

 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       
 β”‚ Integrating Frontend   β”‚ ◄───────────► β”‚ RS-Imzo Frontend SDK   β”‚ ─────► β”‚     RS-Imzo Backend    β”‚ ◄────► β”‚  Integrating Backend   β”‚ 
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        
            β”‚                                        β”‚                                  β”‚                                β”‚                                
            β”‚  (1) Request PKCS#7 with               β”‚                                  β”‚                                β”‚                                
            β”‚      Authorization: Bearer <PUBLIC_KEY>β”‚                                  β”‚                                β”‚                                
            │───────────────────────────────────────►│                                  β”‚                                β”‚                                
            β”‚                                        β”‚  (2) Validate domain + publicKey β”‚                                β”‚                                
            β”‚                                        │────────────────────────────────► β”‚                                β”‚                                
            β”‚   (3) Return PKCS#7 or Unauthorized    β”‚                                  β”‚                                β”‚                                
            │◄───────────────────────────────────────│                                  β”‚                                β”‚                                
            β”‚                                        β”‚                                  β”‚                                β”‚                                
            β”‚  (4) Send PKCS#7 to backend            β”‚                                  β”‚                                β”‚                                
            │───────────────────────────────────────────────────────────────────────────────────────────────────────────►│
            β”‚                                        β”‚                                  β”‚                                β”‚                                
            β”‚                                        β”‚                                  β”‚ (6) Request PKCS#7 or          β”‚  
            |                                        |                                  |     merged PKCS#7 with         | 
            β”‚                                        |                                  |     X-API-Key: <API_KEY>       |  
            β”‚                                        β”‚                                  │◄───────────────────────────────│
            β”‚                                        β”‚                                  β”‚                                β”‚                               
            β”‚                                        β”‚                                  β”‚                                β”‚                                
            β”‚                                        β”‚                                  β”‚ (7) Return parsedPkcs7 or      β”‚                                
            β”‚                                        β”‚                                  β”‚       Unauthorized             β”‚                                
            β”‚                                        β”‚                                  │───────────────────────────────►│                                
            β”‚                                        β”‚                                  β”‚                                |                                
            β”‚                                        β”‚                                  |                                |                                
            β”‚  (9) Return verify/merge/auth          β”‚                                  β”‚                                β”‚                                
            β”‚        result                          β”‚                                  β”‚                                β”‚                                            
            │◄───────────────────────────────────────────────────────────────────────────────────────────────────────────│      
            


πŸ”’ Notes

  • Never expose your API Key on the frontend.
  • The Public Key can be safely used client-side for validation.
  • PKCS#7 is the cryptographic container for signatures β€” it must remain unchanged between verification and merging.
  • If verification fails, ensure that:
    • The apiKey matches the organization that owns the public key.
    • The PKCS#7 was not tampered with or expired.