Search code examples
javaitextdigital-signatureitext7pkcs#7

How to get CMS (PKCS#7) from PKCS#1 Zeal id integration


I am integrating CSC2QR zeal id integration. where i am sending the Base64 URL encoded SHA256 hash (OGRlY2M4NTcxOTQ2ZDRjZDcwYTAyNDk0OWUwMzNhMmEyYTU0Mzc3ZmU5ZjFjMWI5NDRjMjBmOWVlMTFhOWU1MQ==) for signature and in response I am getting PKCS#1 raw signature . I am stuck on how I can use this information to digitally sign the document. I am using itext7 .

"signatures": [
    "uXPiaQOEToyju50OIMrNe5gTstUQhnufmlcxmI9mG5tPCCMDYdfEV4Y+gKkixdzD\r\nZqni1+QAfy8cabRzpq13Puz31qUJ5spDRLfY/VLgBvLZLWTDK0KnJPsPWb36vMY5\r\n8CAn3DSbB02QkOoAafJkcOL3StnXc/JnAszk0lICwIM4lC3IW/pv3tWetrIn6pAJ\r\n7XBSX/zw2tfW9czFFrBaLm7hSe2NlQ1JsMgyLWEBauvFHeyFLdf9rLMM+aCoagRU\r\nD7T4Z31LrxmHFKVelS5dRvZuj8GTYJ78lfYfigSiVMsD8NEY3+YDthAsw2Lmgqs5\r\nMgVmRaQrjSdUMNeDZduFR1IeC/DLmQoBa8oXmeVqgxM0nIplq9gze1FklbPgiZ7G\r\n5zmdD8lnAP9BLawu9P+hC2GZNkeqVep3QzmoO149Iyu0jK8nrhYmxcEEqzaZiklc\r\nIKK7t03Ypst93Kps0OLc0s09A2g2wU+KzuuM+s29VKaE/gua9DKHNtf1iIZDmLtv\r\nRUoQxV9odJvRZwa+UMPsRTVejKb9pbgodiUtieyLq8Kr/NjJl+wnuH8CIiXYWxpe\r\nFoQ+J1teMOok/`sbO2X90SNqg5jvsyFTCBrGSgGWSob1TFghgWgRNiDBienXWWY09`\r\noaii058RhlJDm5l1KhMurBUZsyAre9rs74qj5tntMyQ="
  ]

I am also getting signer certificate as a response Response -:

{
  "authMode": "oauth2code",
  "cert": {},
  "key": {
    "algo": [
      "1.2.840.113549.1.1.11"
    ],
    "len": 4096,
    "status": "enabled"
  },
  "lang": "en-US",
  "multisign": 1
}

Solution

  • I don't know the CSC 2QR API, let alone have finished code for addressing it. Thus, in this answer I'll show up a frame to integrate an arbitrary remote signing API.

    The easiest way to integrate remote signing services with the iText 7 signing API is to implement the IExternalSignature accordingly. That may look like this (code specific to the CSC 2QR API represented by pseudo code):

    public class CSC2QRSignature implements IExternalSignature {
    
        Certificate[] chain;
        String hashAlgorithm = "SHA256";
        String encryptionAlgorithm = "RSA";
    
        public CSC2QRSignature([... parameters you need for CSC 2QR communication ...]) {
            [... request your CSC 2QR Credentials Info and initialize      ...]
            [... chain, hashAlgorithm, and encryptionAlgorithm accordingly ...]
        }
    
        @Override
        public String getEncryptionAlgorithm() {
            return encryptionAlgorithm;
        }
    
        @Override
        public String getHashAlgorithm() {
            return hashAlgorithm;
        }
    
        public Certificate[] getChain() {
            return chain;
        }
    
        @Override
        public byte[] sign(byte[] message) throws GeneralSecurityException {
            byte[] digest = MessageDigest.getInstance(hashAlgorithm).digest(message);
            [... call CSC 2QR Sign Hash for the base64 encoded digest ...]
            [... and return the base64 decoded signature from the response ...]
        }
    }
    

    Using that class you can sign a PDF like this:

    PdfReader reader = new PdfReader(SOURCE_PDF);
    OutputStream os = new FileOutputStream(RESULT_PDF);
    
    CSC2QRSignature signature = new CSC2QRSignature(...);
    IExternalDigest digest = new BouncyCastleDigest();
    
    PdfSigner signer = new PdfSigner(reader, os, new StampingProperties());
    signer.signDetached(digest, signature, signature.getChain() , null, null, null, 0, CryptoStandard.CMS);