{"id":20347792,"url":"https://github.com/itext/ndi-demo","last_synced_at":"2026-01-31T07:31:21.801Z","repository":{"id":216825901,"uuid":"639944157","full_name":"itext/ndi-demo","owner":"itext","description":null,"archived":false,"fork":false,"pushed_at":"2024-02-05T22:21:18.000Z","size":2876,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-25T08:45:03.217Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itext.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-12T15:27:58.000Z","updated_at":"2024-01-12T13:13:49.000Z","dependencies_parsed_at":"2024-11-19T01:46:48.232Z","dependency_job_id":null,"html_url":"https://github.com/itext/ndi-demo","commit_stats":null,"previous_names":["itext/ndi-demo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/itext/ndi-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itext%2Fndi-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itext%2Fndi-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itext%2Fndi-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itext%2Fndi-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itext","download_url":"https://codeload.github.com/itext/ndi-demo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itext%2Fndi-demo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28827900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T23:29:49.665Z","status":"ssl_error","status_checked_at":"2026-01-27T23:25:58.379Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T22:18:07.811Z","updated_at":"2026-01-31T07:31:21.780Z","avatar_url":"https://github.com/itext.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# iText NDI\n\n\nBased on iText 7.1.11\n\nUses the Hash Signing Service (HSS) from the NDI Sandbox (https://demo.sandbox.ndi.gov.sg/home) for signing PDF documents.\nThe signature is PAdES-LT compliant.\n_**Modification of a signature appearance is not yet available**_\n\nThis repo contains two Maven artifacts:\n\n1. *itext-ndi* - the library itself.\n2. *ndi-demo*  - example of the library usage (play2 framework based web app).\n\n\n#### Important note: \nAs of now, (01.10.2020) the Sandbox is temporarily abandoned by NDI. \n\nThe Sandbox API is behind compared to both the Staging and Production API environments, therefore it is highly unlikely this module would work out of the box on either Staging or Production, \nand moreover, **it is not guaranteed the NDI-demo would work correctly in the Sandbox** \nas a reliable API specification is not currently published on https://www.ndi-api.gov.sg/ (hopefully, this is only temporary).\n\nYou can find the HSS spec v 2.11 in the resources.  \n\n\n\n## General information\n\nThe entire communication with the NDI API consists of six operations:\n\n1. The signing request initialization call. \n2. Response containing signing reference\n3. Callback with the user certificate.\n4. The document hash signing call.\n5. Empty response \n6. Callback with the signed hash.\n\nWhere steps 1-3 are called **the first leg** and 4-6 - **the second leg**\n\n\n## How to use\n\n \nThis libary provides the DTO class (``NDIDocument``) together with the service (``NDIDocumentService``) for managing its states.\n\nThe full signing process consists of the following three calls: \n\n```\nNDIDocument documentToSign = ndiDocumentService.init(aContent, aDocName, aNdiUserId, aFieldName, aNDIUserHint, aNdiSigningType);\n//the first callback;\nndiDocumentService.updateFromCallback(NDIDocument aDocument, NdiCallbackMessage aMessage);\n//the second callback;\nndiDocumentService.updateFromCallback(NDIDocument aDocument, NdiCallbackMessage aMessage);\nbyte[] signedPdf = documentToSign.getResult();\n```\n\nWhere \n- ``aContent`` is the content of the source PDF\n- ``aDocName`` - this is used as a document name during a signing session\n- ``aNdiUserId`` - NDI identifier of the signer\n- ``aNDIUserHint`` - ID of the user's access token that should be requested beforehand, using the NDI ASP service.\n- ``aNdiSigningType`` - either `` Type.PN`` or ``Type.QR``.  This parameter defines the way the user accepts \nthe signing session request. In the first case the push notification is sent sent to the user device. \nIn the second one the user should scan a QR code.\nThis code is available after a successful response via ``NDIDocument#getQrCode()``\n\n\nNDIDocumentService depends among others on the **IHssApiClient** which is used for sending requests to the API and handling responses.\n\nHowever, it is up to the application to serve the URL for the NDI Callbacks (steps 3 and 6) _this url can be specified during the client registration using the template ``/\u003ccustom_prefix\u003e/ndi/callback``_ .\nReceived query parameters must be converted into ``NDICallbackMessage`` by ``CallbackConverter``.\nThen the mesage can be validated by ``CallbackValidator`` and then passed to ``NDIDocumentService``.\n\n```\n NdiCallbackMessage callbackMessage = converter.convertParamsToCallbackMessage(aQueryParams);\n callbackValidator.validate(data);\n ndiDocumentService.updateFromCallback(documentToSign, callbackMessage);\n```\n\n#### CallbackValidator\n\nClass for the callback validation. \n`` callbackValidator#validate(NdiCallbackMessage aCallback)`` checks whether this callback's nonce \nmatches with one of the calls made by ``NDIDocumentService``\n\n\u003cem\u003e There is a known bug that the API sends an incorrect nonce in the callback message for the second leg (6)\u003c/em\u003e\n\n \n## Interfaces \n``NdiDocumentService`` also depends on some interfaces. All of them have the default implementation.\n\n#### IHssApiClient\nClient interface of the NDI API hash signing service .\n\n_Implemented by : ``NDIApiService``_\n\nIt is possible to customize the entire ``IHssApiClient`` \nor just ``IWebClient`` - which is being used for HTTPS requests underneath. \n\n#### IChallengeCodeGenerator\nGenerates the 4 digit challenge code that is being sent to the user device on the second leg to identify the signing operation. \n\n_Implemented by : ``ChallengeCodeGenerator``_\n#### INonceGenerator\nGenerates a nonce which cannot be predicted, to ensure the challenge is always unique and not subjected to replay attacks.\n\n_Implemented by : ``NonceGenerator``_\n#### ITSAClient\nTime Stamp Authority client interface from iText 7.\n\n_Implemented by : ``FreeTSAClient``_\n#### IChainGenerator\nCreates a full certificate chain for the user certificate.\n\n_Implemented by : ``ChainFromFileGenerator``_\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitext%2Fndi-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitext%2Fndi-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitext%2Fndi-demo/lists"}