# Implement DVS
In order to create and verify signatures you need to:
- Integrate the DVS JS Client library in your web front end and/or integrate the Android/iOS SDK in your mobile application.
- Alter the endpoint that you have in your back end for creation of the document to return a SHA256 hash digest of the document and timestamp of creation and return those in the response.
- Invoke the sign method of the library/SDK to produce the signature.
- Create an endpoint in your back end, which accepts the signature data and verify it against the MIRACL Trust platform as described in Verify Signature.
# JS Client Library
# Install the Library
In order to sign documents in the browser, you need to include the MIRACL Trust DVS client library and related CSS served from our CDN.
<link
rel="stylesheet"
type="text/css"
href="https://cdn.mpin.io/dvs/css/dvs.css"
media="screen" />
<script
type="text/javascript"
src="https://cdn.mpin.io/dvs/dvs.client.min.js"></script>
# Use the Library
Before using the DVS client library, you need to configure and initialize it.
var dvs = new DVS({
userId: "test@example.com",
clientId: "<YOUR_CLIENT_ID>",
redirectURI: "http://127.0.0.1/login",
pinPolicy: "same",
});
dvs.init(function () {
// You can call the sign method here.
});
Specifying the value same
for pinPolicy
means that the end user must use the
same PIN for signing documents and for authentication. This means that there is
no need to manually manage the identity used for signing with the hasIdentity
,
createIdentity
and deleteIdentity
methods of the library. If not set to
same
you have to create the signing identity:
dvs.hasIdentity(
function success() {
// The user is already registered on the device.
},
function fail() {
dvs.createIdentity(
function success(data) {
// The user is now registered on the device and can sign documents.
},
function fail(error) {
// Creation was not successful.
console.error(error);
},
);
},
);
After you have ensured that the end user has a signing identity either by using
pinPolicy: "same"
or creating one by invoking createIdentity
, you can call
the sign
method. This produces a cryptographic signature of the provided
document, which you are able to store and verify:
dvs.sign(
{
doc: "This is a test document for signing",
hash: "a85675951451ebbcccb4c4d1a41dfe6cbf0f037ef505ffccd3d314930b3d7316",
timestamp: 1608300866,
},
function success(signature) {
// The signature was created successfully.
// You can now send it to your back end for verification.
console.log(signature);
},
function fail(error) {
// The signing was not successful.
// This can happen if the user entered a wrong PIN or
// there was a malicious attempt to temper with the signing.
},
);
You can see a full list of configuration options in MIRACL Trust DVS Web Plugin.
# Examples
<!doctype html>
<html>
<head>
<title>DVS Same PIN</title>
<link
rel="stylesheet"
type="text/css"
href="https://cdn.mpin.io/dvs/css/dvs.css"
media="screen" />
<script
type="text/javascript"
src="https://cdn.mpin.io/dvs/dvs.client.min.js"></script>
</head>
<body>
<script type="text/javascript">
var dvs = new DVS({
userId: "test@example.com",
clientId: "<YOUR_CLIENT_ID>",
redirectURI: "http://127.0.0.1/login",
pinPolicy: "same",
});
dvs.init(function () {
dvs.sign(
{
doc: "This is a test document for signing",
hash: "a85675951451ebbcccb4c4d1a41dfe6cbf0f037ef505ffccd3d314930b3d7316",
timestamp: 1608300866,
},
function success(signature) {
console.log(signature);
},
function fail(error) {
console.error(error);
},
);
});
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<title>DVS Different PINs</title>
<link
rel="stylesheet"
type="text/css"
href="https://cdn.mpin.io/dvs/css/dvs.css"
media="screen" />
<script
type="text/javascript"
src="https://cdn.mpin.io/dvs/dvs.client.min.js"></script>
</head>
<body>
<script type="text/javascript">
var dvs = new DVS({
userId: "test@example.com",
clientId: "<YOUR_CLIENT_ID>",
redirectURI: "http://127.0.0.1/login",
pinPolicy: "different",
});
function signExample() {
console.info("Start signing");
dvs.sign(
{
doc: "This is a test document for signing",
hash: "a85675951451ebbcccb4c4d1a41dfe6cbf0f037ef505ffccd3d314930b3d7316",
timestamp: 1608300866,
},
function success(signature) {
console.info("Successful signature:");
console.log(signature);
},
function fail(error) {
console.error(error);
},
);
}
dvs.init(function () {
dvs.hasIdentity(
function success() {
signExample();
},
function fail() {
console.info("Start registration");
dvs.createIdentity(
function success(data) {
console.info("Successful registration:");
console.log(data);
signExample();
},
function fail(error) {
console.error(error);
},
);
},
);
});
</script>
</body>
</html>
# Verify Signature
Signature verification is done by making a request to the /dvs/verify
endpoint
of the MIRACL Trust platform from your back end. If the verification is
successful in the response you receive a certificate in the form of a signed JWT
(JSON Web Token). The payload of the request must contain the signature
object
produced from the client library, the timestamp
of the signing (must be the
same timestamp passed to the sign method of the client library) and a type
parameter set to verification
.
# Verification Request Example
curl \
--user "${YOUR_CLIENT_ID}:${YOUR_CLIENT_SECRET}" \
--data '{
"signature": {
"dtas": "WyIyNWUwYzMxY2ZlYjk5NGNjYWY3ZWE4OGQxYjBiNmQwMDMyM2MxNDI5ZWVjMzEzNzFiZTVmNTM3NjhiMjcxNjBkIiwiMjVlMGMzMWNmZWI5OTRjY2FmN2VhODhkMWIwYjZkMDAzMjNjMTQyOWVlYzMxMzcxYmU1ZjUzNzY4YjI3MTYwZCJd",
"hash": "74657374",
"mpinId": "7b22696174223a313631343736333336322c22757365724944223a2274657374406578616d706c652e636f6d222c22634944223a2238366364336536342d663634312d343136612d626638302d363462396237656566386561222c2273616c74223a2263483141545930367879754555574d667551466a4351222c2276223a352c2273636f7065223a5b22647673225d2c22647461223a5b5d2c227674223a22647673227d",
"publicKey": "16ef9515c8c35a3b11dc04f256c721a57b16857a612efe41ccfbf22514926b3511d51044366da78da224529447c04a9cf9dc4fbe142e783b02f9566e88b49ba700a5820ab2eafd9a541e1e37a7c04a1f75bfc8646979fb90886022a9c05b51b82382a1ba59a5ebad707930ef0692bba152b8faf596eead347a933d0b15ca2d0a",
"u": "040cbde168ab69a65fff10b0cde73dd2e19d0d230cc7011247d2e476540ffaf3800a92075babe5e823313a5c1d020c4318fb68bdea6dd19b64837061451700525e",
"v": "041be8fa9de40ed2925ca446048a2896532b88762f8b6e090f25f33a437c50396f09d441a500f7fa9646df5cbad7f4c8c2426c8e29e252d1a9c70ffa6d7dcd9201"
},
"timestamp": 123,
"type": "verification"
}' \
https://api.mpin.io/dvs/verify
# Verification Response Example
{
"certificate": "eyJhbGciOiJSUzI1NiIsImtpZCI6InMxIn0.eyJjQXQiOjE2NDk0MDQ1ODAsImV4cCI6MTY0OTQwNDU5MCwiaGFzaCI6Ijc0NjU3Mzc0In0.BoMXXJVdiJ3TNQ1m_qz2GMo9J9EniUHJz14XMmVOBJPBWjw6UWTn2G2henNOauB7t6oBqqtLhRudLr3KY1kLgWorOSXlvISoZicEFGsmUfEXS-hxP3d01acE0cRnqMmi1Au4VXbREdwLy7I7Cwb4ptLrziYvkEVh7KdbAMsD6Bw"
}
# Verify Certificate Validity
After you receive the certificate you need to verify its validity by using the JWKS (public JSON Web Key Set) published on the https://api.mpin.io/dvs/jwks endpoint. Here is an example response from this endpoint:
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "s1",
"n": "kWp2zRA23Z3vTL4uoe8kTFptxBVFunIoP4t_8TDYJrOb7D1iZNDXVeEsYKp6ppmrTZDAgd-cNOTKLd4M39WJc5FN0maTAVKJc7NxklDeKc4dMe1BGvTZNG4MpWBo-taKULlYUu0ltYJuLzOjIrTHfarucrGoRWqM0sl3z2-fv9k",
"e": "AQAB"
}
]
}
The header of the JWT certificate contains the algorithm and the ID (kid
) of
the key used for signing the token in the following form:
{
"alg": "RS256",
"kid": "s1"
}
When validating the signature of the token, the key with the same kid
from the
https://api.mpin.io/dvs/jwks response needs to be used.
Most JWT libraries have support for remote key sets and signature verification. For a list of libraries implementing JWT decoding and signature verification, see jtw.io.
# Certificate Payload
The JWT certificate contains a payload in the following form:
{
"cAt": 1649404580,
"exp": 1649404590,
"hash": "74657374"
}
You need to ensure that the hash in the certificate matches the hash of the document that was signed. As the certificate only serves as proof for the current verification request, it is quite short-lived. There is no need to store the certificate. If necessary, you can make another verification request to ensure the validity of the signature.
# Handle JWKS rotation
When necessary, MIRACL Trust can change the signing key for the JWT certificate.
Certificates issued after the rotation have the new kid
in their header. Your
implementation needs to ensure that the JWKS is fetched again from the
https://api.mpin.io/dvs/jwks endpoint when it encounters a new kid
.