Search code examples
restdigital-signatureelectronic-signature

get signatureValue from getDataToSign method in DSS


I use SD-DSS open source solution to sign a document digitally. I checked dss-documentation page, but not sure, how to get signatureValue, which is in sample request. As I interpret, I has to use output of getDataToSign, the digest as signatureValue, but there is mismatch between these values in sample REST project.

Output of getDataToSign is:

{{

{ "bytes" : "MYIBETAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xODAzMjYwODEyMDlaMC0GCSqGSIb3DQEJNDEgMB4wDQYJYIZIAWUDBAIBBQChDQYJKoZIhvcNAQELBQAwLwYJKoZIhvcNAQkEMSIEIBhfjbMicf4l9WGm/JOLLiZDBuwwTtpRgAfRdkgmOBlpMHcGCyqGSIb3DQEJEAIvMWgwZjBkMGIEIALz68oBYydCU7yAnSdJjdQbsDFtfmsGaWARXeFVWJ2cMD4wNKQyMDAxGzAZBgNVBAMMElJvb3RTZWxmU2lnbmVkRmFrZTERMA8GA1UECgwIRFNTLXRlc3QCBi7WFNe7Vw==" }
}}

Value in signDocument request:

{{ "signatureValue" : { "algorithm" : "RSA_SHA256", "value" : "AQIDBA==" },}}

UPDATE:

I use these requests:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getDataToSign xmlns:ns2="http://signature.dss.esig.europa.eu/">
<dataToSignDTO>
<parameters>
<BLevelParams>
<trustAnchorBPPolicy>true</trustAnchorBPPolicy>
<signingDate>2019-01-01T01:01:01.464Z</signingDate>
</BLevelParams>
<digestAlgorithm>SHA256</digestAlgorithm>
<encryptionAlgorithm>RSA</encryptionAlgorithm>
<signatureLevel>PAdES_BASELINE_B</signatureLevel>
<signaturePackaging>ENVELOPED</signaturePackaging>
<signingCertificate>
<encodedCertificate>${#cert}</encodedCertificate>
</signingCertificate>
</parameters>
<toSignDocument>
<bytes><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="ref1"/></bytes>
</toSignDocument>
</dataToSignDTO>
</ns2:getDataToSign>
</soap:Body>
</soap:Envelope>


<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:signDocument xmlns:ns2="http://signature.dss.esig.europa.eu/">
<signDocumentDTO>
<parameters>
<BLevelParams>
<trustAnchorBPPolicy>true</trustAnchorBPPolicy>
<signingDate>2019-01-01T01:01:01.464Z</signingDate>
</BLevelParams>
<digestAlgorithm>SHA256</digestAlgorithm>
<signatureLevel>PAdES_BASELINE_B</signatureLevel>
<signaturePackaging>ENVELOPED</signaturePackaging>
<signingCertificate>
<encodedCertificate>${#cert}</encodedCertificate>
</signingCertificate>
</parameters>
<signatureValue>
<algorithm>RSA_SHA256</algorithm>
<value>${#datatosign}</value>
</signatureValue>
<toSignDocument>
<bytes><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="ref1"/></bytes>
<name>dsstest</name>
</toSignDocument>
</signDocumentDTO>
</ns2:signDocument>
</soap:Body>
</soap:Envelope>

Code to generate signatureValue:

try (Pkcs12SignatureToken token = new Pkcs12SignatureToken("src/main/resources/user_a_rsa.p12", new PasswordProtection("password".toCharArray()))) {

        List<DSSPrivateKeyEntry> keys = token.getKeys();
        for (DSSPrivateKeyEntry entry : keys) {
                System.out.println(entry.getCertificate().getCertificate());
        }

        ToBeSigned toBeSigned = new ToBeSigned("Hello world".getBytes());
        SignatureValue signatureValue = token.sign(toBeSigned, DigestAlgorithm.SHA256, keys.get(0));

        System.out.println("Signature value : " + Utils.toBase64(signatureValue.getValue()));
}

Solution

  • DSS is providing to you in getDataToSign the digest to be signed with the private key corresponding with the certificate you sent.

    You have to digitally sign that value using the specified algorithm and send the result to signDocument. In your case RSA PKCS#1 with SHA256

    Pseudocode

    var digestToSign = getDataToSign(document, params)
    var signatureValue = PKCS#1_v1.5(privateKey, digestToSign, SHA256)
    var finalDocument = signDocument(signatureValue)
    

    After this, DSS will build the final signed document.