Our demo showcases a Solid-based Web where the integrity of a Web resource's representation is directly verifiable using its content and its identifier.
Authors: Christoph Braun, and Tobias Käfer from AIFB @ Karlsruhe Institute of Technology (KIT), Germany
Watch our full-length video » Check out the live demo » Get the code »Our demo showcases a Solid-based Web where the integrity of a Web resource's representation is directly verifiable using its content and its identifier. A Web resource is available at some URI described in RDF. Each such representation includes a Linked Data Signature, which we model using RDF-star. In addition, each Web resource's URI includes the signature's value as a suffix, which we call Signed URI. In a Web of such resource representations, modifications to a resource are detectable unless all resources that transitively reference the original are updated as well. We present a Solid-based Web application where such a Web of resources with self-verifying representations can be created and verified.
When accessing our live demo, you get an in-app tutorial!
We summarize the tutorial here for reference (if you do not want to follow the in-app tutorial):
We showcase Linked Data Signatures, Signed URIs and the
resulting document graph.
The app has two views:
Your typical URI wont work (it needs to be a Signed URI). Try this example:
https://uvdsl.solid.aifb.kit.edu/public/eswc/demo__0xf47c978f0bf4dda7d3e868a1774d7160d4d80a61709458b78dd7b70724afe2599c6137ce288c97e5d3f55bcc4b3f81e5f5f09b8e645c92cbec0e4413d7fc60fbCopy and paste this URI to the input text field at the top and hit enter (or the button).
That is one colorful graph of documents. Cool.
Each node represents a document that is available at a Signed URI.
Each edge represents a link to another document via a Signed URI.
A green colored node indicates that the all verification steps were successful.
A red colored node indicates that some verification step was unsuccessful.
Click on the
red colored node
to inspect the resource in detail!
You will be taken to the other view of this app, but we will be there to help you.
Oh my! All three checks were unsuccessful:
Looking closely, we commented out the second object <#cool> which a quoted triple exists for in the sec:proofOf object list of the _:signature.
Looking closely, we changed the last element of the signature.
Looking closely, the aforementioned change makes the signatures not match anymore. The Signed URI has still the original signature.
If you want to check the error messages again, simply GET the resource again.
Let's now check out the public key that this message was signed with!
The Public Key is also signed!
Here you have the public key that is used to verify the two other resources.
Moreover, this key can be used to verify its own information resource!
This way, the owner can prove possesion of the associated private key.
For this resource, all verification checks are succesfull. Looks good!
Additionally, you can now see that we model the information on the key
itself using RDF instead of some string encoding in JSON format.
All of these RDF statements are covered by the signature (see the RDF-star?).
You have successfully completed part 1 of the demo!
To continue the demo, please log in with your WebId. (Get a Pod!)
You will need your Solid Pod to store your keys.
Then you can sign your own RDF graphs!
Create your own signed RDF graph!
If you just logged in, you probably see the Graph Visualiser and the Welcome-Dialog.
Click on the button "Skip to Part 2".
It will take you to a screen where you have a textfield for a URI and a textarea for the content.
The textfield at the top defines the URI you want to do actions on. You can delete (Yes, HTTP
DELETE)
any
resource or put (Yes, HTTP PUT) a resource there (if you are authorized to do so).
For this example, you can choose a URI from your Pod, e.g. in the style of
https://your.pod/public/eswc-demo
# e.g. https://alice.inrupt.net/public/eswc-demo # use yours!
Substitute your.pod with the location of your pod.
When using the in-app tutorial you can simply copy and paste the suggested URI from the dialog.
The content text area takes RDF in turtle syntax, e.g.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
<#this> rdfs:seeAlso <https://uvdsl.solid.aifb.kit.edu/public/eswc/demo__0xf47c978f0bf4dda7d3e868a1774d7160d4d80a61709458b78dd7b70724afe2599c6137ce288c97e5d3f55bcc4b3f81e5f5f09b8e645c92cbec0e4413d7fc60fb> .
As you can see, we already provided you with a link to an existing resource at a Signed URI.
You can edit the resource as you like but we would suggest you leave that link in. Otherwise,
you won't see your resource connected to the existing graph.
Do so now before you continue.
Sign the Resource!
Simply:
Do so now before you continue.
Create a Key Pair and sign the resource:
With the current dialog, you can create new keys and pick then from existing keys for signing.
The keys are stored in your Pod. You can find them in the `keys` directory in your
private and public directories, e.g. https://your.pod/private/keys/ .
After the signature has been created, you will notice that the signature value has
automatically been appended to the URI. Now it is a Signed URI.
Save the Resource!
Simply:
Do so now before you continue.
Check out your addition to the Graph:
After you successfully saved the resource, you can admire your addition to the document graph by
Do so now before you hit continue.
Green boxes indicate a valid Linked Data Signature and a matching Signed URI, whereas red boxes indicate an verification error, e.g. invalid Signature, mismatching signature value and Signed URI, not all quoted triples are asserted (specific to our case, not a general requirement), or any other error that may occur when dereferencing a URI.
Play around :)
Thank you for trying out our demo!
If you have any remarks, questions or ideas for improvement, please let us know!
You are always welcome to open an issue in the GitHub repository :)
Imagine that we were to modify our document that you just referenced from your document. Assume that we recalculate the Linked Data Signature.
Your document would still point to the URI of our original document.
If we update our resource at the same URI, the signature values do not match. If we had not recalculated the Linked Data Signature, the signature would be invalid. To avoid this, we have to create a new document at a new Signed URI.
You could choose to also update YOUR resource, i.e. creating a document at a new Signed URI. But not everyone that references our resource may be do alike. Or, you may simply not even update your resource in the first place.
The more documents reference a particular document, the more documents need to be "updated" and the more users need to be convinced to do so for a non-evident modification of a resource.
We re-use terms from the security vocabulary which is still under development and not fixed yet. Additionally, we model the cryptographic keys also in RDF using a self-defined ontology .
An Example, available here :
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dc: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix sec: <https://w3id.org/security#> .
_:signature a sec:Signature;
dc:created "2022-02-04T10:39:31.981Z"^^xsd:dateTime;
dc:creator <https://uvdsl.solid.aifb.kit.edu/profile/card#me>;
sec:publicKey <https://uvdsl.solid.aifb.kit.edu/public/keys/52c13ca0-85a0-11ec-ad2c-5bab2b4d9578.ttl__0xb7898c987e2e5ba9ae6b9f28dbf89534b6d642b5d55bf2ff88555add2a55afb7f068f49a54804640c6b3c70fb8e18e061daa2b71b22e065f01294c29c6220db6#key>;
sec:canonicalizationAlgorithm "Hogan2017";
sec:digestAlgorithm "SHA-256";
sec:digestValue "9fcefe55113bc893979d7f23ecdac5704e8606b6f5c5c4c51b536267a274cc8e"^^xsd:hexBinary;
sec:signatureAlgorithm "ECDSA";
sec:signatureValue "9a4cdd00f9fd24288c7cccf49e5365e518e8d459590f11c16be7b3ebc802af87bccc6779b27312078dac54da318d1180b9e92f9c82244e14ef78aaf0fbd7e83e"^^xsd:hexBinary;
sec:proofOf << <#this> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <#test> >>, << <#this> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <#cool> >>.
<#this> a <#test>, <#cool>.
For modeling a closed set of triples signed by the signature, we would have liked to use an RDF list but the parser of N3.js does not like RDF lists of RDF-star triples (see this issue).
To calculate the signature, we first need to canonicalise the RDF graph. We use the algorithms of Hogan [3] for canonicalising as it is able to handle blank nodes most gracefully. As message digest algortihm, we use SHA-256. We further use the Elliptic Curve Digital Signature Algorithm (ECDSA) with curve P-256 for creating and verifying the signature value.
The public key linked from the example above, modelled with our own ontology due to the lack of another (its signature is omitted for brevity):
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix sec: <https://w3id.org/security#> .
@prefix jwk: <https://purl.org/solid-web-ldsig/jwk/vocab#> .
<#key> rdfs:label "main_key" ;
sec:controller <https://uvdsl.solid.aifb.kit.edu/profile/card#me>;
sec:publicKeyJwk <#jwk> .
<#jwk> jwk:alg "ES256" ;
jwk:crv "P-256" ;
jwk:ext true ;
jwk:kty "EC" ;
jwk:x "kmiMVyVQ0VyCE5a7PJCmoUh1JG6B-RdC5zs3edgBq4w" ;
jwk:y "TY1dPmrbPiOynP987eAgd00sLpgnV2ps1uLxU89GRng" ;
jwk:key_ops "verify" .
With this public key, the signature of our example can be verified.
When modeling Linked Data Signatures, we use RDF-star instead of Named Graphs [2] to reference the set of signed signed triples:
RDF-star allows for quoting triples, i.e. referencing without asserting. We argue that the Linked Data Signature only provides meta-information on the signed triples and does not necessarily have to assert those triples as true. This may be useful when the truth-value of the signed triples may change in the future. A digital student id card, for example, becomes invalid when the student graduates. The signature, however, remains valid as it makes no statement about the truth-value of the signed triples.
Inspired by Trusty URIs [5], Signed URIs include the signature value as a suffix. The hexadecimal value of the signature is appended to the URI and delimited by two underscores. We trim the signature suffix prior to resolving relative URIs in RDF graphs. An example:
https://uvdsl.solid.aifb.kit.edu/public/testing.ttl__0x9a4cdd00f9fd24288c7cccf49e5365e518e8d459590f11c16be7b3ebc802af87bccc6779b27312078dac54da318d1180b9e92f9c82244e14ef78aaf0fbd7e83e
Now, not only can the retrieved content be verified but also be expected:
When the signature value of the Linked Data Signature does not match the URIs signature suffix,
a different content has been served than originally published.
A document graph of documents with Linked Data Signatures available at Signed URIs is created. When a document is modified, its signature value changes, the existing Signed URI mismatches and the modification becomes discoverable. For a modification to become undiscoverable, a new Signed URI is to be used and all documents that (transitively) reference the original documents are to be updated (with respective new Sigend URIs) as well. Since these documents are not necessarily under control of one user but many different, e.g. messages in a chat or comments on a post, all users have to agree on such undiscoverable updates. Otherwise, some evidence will remain. An example:
We rely on the Solid Protocol: Users are identified by their WebID, are authenticated using Solid-OIDC and store data in personal online data storages (Pods) under user-defined access control. An early description about the Solid project is provided in [6].
The integrity of Linked Data is typically verified by calculating and comparing cryptographic hashes of the underlying RDF graphs. We use the algorithm of Hogan [3] for graph canonicalisation as it handles blank nodes most gracefully. While some may sense a possible blockchain use-case, as previously presented in [1], we argue: The Web is all we need.
Trusty URIs [5] aim to make digital resources verifiable, immutable and permanent by by extending the usual URI scheme with a cryptographic hash of the resource as a URI suffix. Our approach builds on and extends the conceptional idea of Trusty URIs with digital signatures to Signed URIs.
Nanopublications [4] aim at publishing data on the Web using Trusty URIs such that links among nanopublications contribute to data integrity. With only hash values ensuring integrity of data, authorship of publications is not preserved. The centralised yet distributed nanopublication-server-network ensures publications' discoverability, permanence and immutability.
Web Publishing using Named Graphs has first been proposed by Carroll et al. [2]. The approach relies on ontology-defined terms to indicate if a graph is to be interpreted as assertative or non-assertative by an information consumer. We use RDF-star instead of Named Graphs, thereby allowing the information creator to normatively define which triples are (non-)assertative.
The code of our tool is available on GitHub.