Stream: connectathon mgmt
Topic: Digital Signatures Track
Alexander Zautke (Nov 02 2018 at 11:41):
Hi everyone!
I'm currently implementing the $document operation in Vonk incl. digital signatures. These signatures are in our implementation based on JSON Web Keys and JSON Web Signatures. I was wondering if there is any interest in doing a track on digital signatures at the next WGM?
It would be awesome if we could explore some of the edge cases around digital signatures and FHIR.
Grahame Grieve (Nov 06 2018 at 20:50):
I'm interested in that
Grahame Grieve (Nov 06 2018 at 20:50):
@John Moehrke ...?
John Moehrke (Nov 06 2018 at 21:26):
Yes I am interested. So what is the use-case? As in who is the target of the signature? What is the risk the signature is protecting against?
Grahame Grieve (Nov 06 2018 at 23:48):
no-repudiation?
John Moehrke (Nov 07 2018 at 13:37):
that is a technical 'how', not a use-case 'what'. Non-Repudiation has many flavors. Non-Repudiation of authorship, Non-Repudiation of awareness of data, Non-Repudiation of receipt of data, Non-Repudiation of involvement... Some of these can be done the same way, others are different tech.
Alexander Zautke (Nov 07 2018 at 16:37):
Our main focus is currently protecting integrity and verifying authorship
John Moehrke (Nov 07 2018 at 19:32):
what is your current solution? Are you using Provenance.signature?
Alexander Zautke (Nov 07 2018 at 20:05):
I am still working on getting a correct signature into Bundle.signature after using $document on a composition. I have an implementation running which is able to generate new JWKs which can then be used in a JWS. Some parts of RFC7515 are a bit tricky, so it's work in progress.
For me, the authorship problems starts even earlier, how should the signature key be selected by a server, based on a SMART on FHIR token?
Of course, you'll also have challenges to solve on the receiving side, how do you deal with the incoming signature? That's some of the questions I would like to discuss.
John Moehrke (Nov 07 2018 at 20:22):
okay, so you are currently using Bundle.signature. I was not clear from the FHIR spec if this was intended or Provenance with a signature.
John Moehrke (Nov 07 2018 at 20:23):
Yes, the 'who' signs is wrapped in the question I had on the use-case. In the case of a $document, this is really authored by the machine and thus the machine is the best choice for who signs... Yet that signature is not all that helpful.
John Moehrke (Nov 07 2018 at 20:26):
a use-case that is really wanting the true author as the signer, would have a point in the workflow of creating a document, where the document is seralized, reviewed by the author, and signed. That seralized Bundle is then carried around as a signed Bundle. thus a DocumentReference is created.
John Moehrke (Nov 07 2018 at 20:27):
I am less a fan of signatures inside the object they sign, as any exclusion rules can be leveraged by malicious intent to hide malicous content intended to look like it was signed.
John Moehrke (Nov 07 2018 at 20:28):
I prefer that the Bundle be created without a signature, and that an external signature be created. A Provenance is a good solution in this case.
Grahame Grieve (Nov 07 2018 at 20:28):
that doesn't address any of the actual questions
John Moehrke (Nov 07 2018 at 20:28):
Hmm, I thought I was.
Grahame Grieve (Nov 07 2018 at 20:29):
.. who signs?
John Moehrke (Nov 07 2018 at 20:29):
the signature for authorship should be by an identity that is the author. If you are using SMART-on-FHIR for authorship workflows, then yes. But if you are using native EHR function for authorship workflows then that identity comes from native EHR function.
John Moehrke (Nov 07 2018 at 20:31):
Most recipients of a document tend to ignore signatures. They just get in the way. They tend to trust the pathway that the data came to them... The exception however is why we want a signature.
Grahame Grieve (Nov 07 2018 at 20:32):
but anyway, let's stick with the question about the location of the signature... so you generate a document with $document.... now what do you do with the provenance?
John Moehrke (Nov 07 2018 at 20:32):
One could put workflow rules that indicate that an incoming object with a signature MUST be validated. but you then must put in place rules for what to do when the signature fails due to the various soft reasons for failure (identity couldn't be confirmed, but the signature was valid to the identity given; revocation couldn't be confirmed, but signature validated, etc)
John Moehrke (Nov 07 2018 at 20:35):
so there are three solutions available today, right. Put the signature in Bundle.signature, Put a Provenance in the Composition specifically for overall Provenance and thus Provenance.signature, or External signature using Provenance.target that points at the Bundle.
John Moehrke (Nov 07 2018 at 20:36):
I hear Alex indicating Bundle.signature
John Moehrke (Nov 07 2018 at 20:38):
Bundle.signature is 0..1; so there can be only one declared purpose of that signature. I expected a Bundle.signature to almost always be a "Source" signature type -- http://build.fhir.org/valueset-signature-type.html
John Moehrke (Nov 07 2018 at 20:39):
I don't know if there has been any past discussion of how that signature is calculated such that it excludes the Bundle.signature element.
John Moehrke (Nov 07 2018 at 20:40):
This is common in XML-Signature, but I hear we are talking JSON encoded Bundle, thus a JSON seralization, and a JSON signature http://build.fhir.org/datatypes.html#JSON
Grahame Grieve (Nov 07 2018 at 20:40):
apparently there has not been any discussion about that
Grahame Grieve (Nov 07 2018 at 20:42):
the reason encapsulated signatures are popular is because "an incoming object with a signature" has a defined meaning. If you put the signature in a provenance.... what does that mean?
John Moehrke (Nov 07 2018 at 20:44):
I don't agree that one is more obvious than the other.
John Moehrke (Nov 07 2018 at 20:45):
and I stand by my assertion that 99% of the time the recipient is going to ignore (and store) the signature.
John Moehrke (Nov 07 2018 at 20:46):
anyway... so rfc7515 defines how to do a JWS with the content within the JWS... In our case we want a detached signature... so we first put it in so the signature can be calculated, then we remove it, the resulting JWS is what gets put int the .signature.data element
John Moehrke (Nov 07 2018 at 20:49):
right?
John Moehrke (Nov 07 2018 at 20:51):
https://tools.ietf.org/html/rfc7515#section-5
John Moehrke (Nov 07 2018 at 20:53):
I have not done this.. my experience is with xml-signature... but it sees rather similar, kind of...
Grahame Grieve (Nov 09 2018 at 00:05):
if the signature is separate, how do I know whether there is a signature I should validate? how do I know where to look? how many attack vectors arise when I go looking?
John Moehrke (Nov 09 2018 at 14:16):
This is why I asked for the use-case and the target of the signature. If the use-case is as a confirmation that something I just received is whole, then yes it is important for the signature to be clearly part of the transport. However in this case, it is a quick failure-mode when the signature is not clear.
Most signatures are signatures used to prove the veracity of the data when that veracity comes into question. These use-cases are not done inline with a workflow, but are triggered by an investigation that might be triggered by an incident, a report, etc. In these cases, the effort it takes to do a reverse search for Provenance is not a hard thing to do.
So the use-case and who is the signature intended for, is very important. The current specificaiton of a Bundle.signature is good for the first use-case, and there is no harm of it being only one type of signature as the signature type is clearly to validate the content one is about to consume/import. The Provenance.signature is good for the other use-cases that are more complex and would include counter-signatures, co-signatures, signatures of authoriship, signatures of review, signatures of authority, signatures of assembling...
John Moehrke (Nov 09 2018 at 14:20):
I think that the Provenance.signature method could be used in both kinds of use-case. I can visualize two variants: 1) where the transport of the composition bundle includes the Provenannce; much like this model for ANY kind of Resource. Where a signature is needed, it can always be added to a transport bundle. 2) The Composition itself could include a section which is the Provenance resource that has the signature. This would be rather similar to a document that has built-in wet-signature lines, thus paper document has ink signature as a section.
Grahame Grieve (Nov 09 2018 at 20:27):
the only requirement I saw for signature verification was in electronic prescriptions, and it required signatures to be tested all the time
John Moehrke (Nov 09 2018 at 21:06):
every time? Or on dispensing? The prescription signature regulation I know of is only for Schedule 2 drugs, and does require D-signature for writing a prescription. I think the intent is that processing of that prescription requires signature validation. This to protect against the risk of malicious (drug seeking) prescriptions that are not truly valid. But I don't think that 10 years later when reviewing the drugs a patient has taken requires that the signature be validated.
Grahame Grieve (Nov 10 2018 at 05:42):
dispensing, yes
Alexander Zautke (Nov 12 2018 at 10:33):
To rewind a bit back to the discussion about the author of the signature: of course in the end, in the case of $document, the author of the document is the server. On the other hand, in our use case, this interaction is the only one which is directly initiated by a user (the signer).
For your background, in our use case, we gather information from various places within an university clinic. A bunch of different systems is pushing data to a central FHIR server. Additional, we have a process where a user of our system is filling out a questionnaire in cooperation with a patient.
This questionnaire in enriched with the data that has already been captured. The questionnaire is then printed out and signed by the patient.
Meanwhile, the server is creating a bundle of exactly the same information, using $document, which is then stored locally for documentation purposes, as well as for research in an anonymized form.
Now, the challenge is that we need to trace the user who has acknowledged the physical signature of the patient. This could be conveniently done by sending a token with the $document request, based on which an individual key could be chosen. So it's not that much about capturing the signature of the patient but to guarantee the correctness of the captured and authenticated data.
In my opinion, it would make life more difficult if we would need to carry around a DocumentReference or a Provenance resource. Bundle.signature is totally sufficient in our use case, because we don't need any additional metadata attached to the signature. Of course, it would not be hard to do a reverse chaining search for Provenance, but we would then need to indicate inside the bundle that the bundle is "logically" not complete without the Provenance. Both should always be requested at the same time. Even if the receiving system chooses to ignore the signature if it's not capable of handling it. In our use case, the bundle travels through alot of different places, so that might get tricky.
Of course we can discuss if including Provenance inside a signed bundle makes more sense. I'm looking into how much more work that would be in terms of calculating the signature.
Alexander Zautke (Nov 12 2018 at 10:36):
CC: @Gustav Vella
John Moehrke (Nov 12 2018 at 13:37):
So, we can focus on use of Bundle.signature for documents. That is a good place to start. You indicate this technically satisfies. However I am still not clear on who is validating the signature, why are they validating the signature, when are they doing that, and why are they validating the signature? (Note, I did mention two very different uses of Provenance, one classic and thus external, one as a formal section in the Composition)
Do you have a fixed encoding (json vs xml) that you know the document will always be consumed? Or do you need two types of signature for the various bundle encoding?
Alexander Zautke (Jan 06 2019 at 15:10):
Sorry for taking such a long time to respond, I haven't been able to work on this project for quite a while!
Good news first: I finished coding two libraries in .NET which support the creating of JSON Web Keys and JSON Web Signatures.
I published both of them as open-source:
- https://github.com/alexzautke/JWS
- https://github.com/alexzautke/JWK
Both projects only rely on system-provided crypto functions and solely focus on formatting the JSON according to the RFCs.
So, it should be fairly easy to port them to a different runtime, if anyone is interested in using these projects for a different FHIR server.
I will try to incorporate support for both libraries into Vonk's $document operation. It open-source, too, just in case someone wants to help out ;)
See https://github.com/FirelyTeam/Vonk.Plugin.DocumentOperation.
@John Moehrke back to your questions. To make things a bit more concrete: My use case is questionnaires used in cancer-research as clinical trial forms. We get (FHIR) data from primary systems and our EHR. Additionally, we are running a service for filling out these questionnaires. While doing so, data that we can derive from the EHR / primary systems gets incorporated automatically. When a questionnaire is submitted by a practitioner, all data is transformed into a FHIR document (by calling $document). This process takes place in a distributed system, meaning that there exist multiple instances of the system used to fill out the questionnaires. They may even be distributed across different clinics.
In the end, all data is delivered to a single FHIR endpoint and stored in a database.
What we want to achieve with digitally signing the document is that we want to be able to show:
a) That no record was altered after submitting the FHIR document to the central FHIR server
b) Who was responsible for submitting the FHIR document
As to creating the signing input, my idea was to do it in the following way:
1. Create a Provenance resource for the complete Bundle, including the signature which covers every element of the bundle incl. the Provenance resource itself except the signature element. With this solution, we would have non-repudiation of the content.
2. Create a new signature including the signature above as well as the "meta" content of the signature in the Provenance resource. Based on this we have a guaranteed way of showing the authorship based on the who[x] element in the signature. Of course, you could do the last part based on the key/signature alone, however, I think it's good to have this information in the resource signature element as well.
Does this sound good to you?
Last question, just out of curiosity. I see that signature.when could theoretically be useful, however, I was wondering what's the reasoning to make it 1..1?
John Moehrke (Jan 06 2019 at 17:55):
That sounds like it might be a bit over-engineered, but not in a bad way. I am not sure how useful the second Signature is, or where you are storing that.
John Moehrke (Jan 06 2019 at 17:57):
as to why Signature.when is 1..1 is to make the date/time of the signature mandatory. It is one of the most useful things that all apps would want to have in a nice FHIR readable form, rather than expecting everyone to understand JWS or XML-Signature. This is the usecase for all the elements in the Signature resource, they are there for convenience of the broadest apps. Where as apps that must validate the digital signature must be able to process correctly the underlying digital-signature standard used with trust mechanisms used in that object.
Alexander Zautke (Jan 06 2019 at 18:16):
The second signature would go into Bundle.signature. The whole point would be to get a signed version of the meta data attached to the signature in the Provenance resources. You can only reasonably provide these information after creating the signature. But than there is almost no way of trusting it other than creating a second signature.
Alexander Zautke (Jan 06 2019 at 18:18):
Makes sense, just didn’t expected that “when” is an attributed that is often needed for a signature.
Alexander Zautke (Jan 06 2019 at 18:24):
Now, this would led to the question if it would be reasonable to include the signature algorithm inside the signature element as well? Or is the receiver of a signature expected to try to parse the signature?
Alexander Zautke (Jan 06 2019 at 18:25):
How would I know that I’m receiving a JWS instead of a XML signature? Is this something that would be expected in an implementation guide instead?
John Moehrke (Jan 06 2019 at 21:34):
How would I know that I’m receiving a JWS instead of a XML signature? Is this something that would be expected in an implementation guide instead?
possibly, but everywhere else in FHIR when there is a blob, we have a mime-type for that blob... so it seemed natural. I see no reason why it would not be possible to fill out the mime-type.
The other reason is that Provenance can hold multiple signatures, each with a different mime-type. Thus you could sign twice with two different signature technology.
John Moehrke (Jan 06 2019 at 21:36):
Makes sense, just didn’t expected that “when” is an attributed that is often needed for a signature.
To be very specific. Not all applications can validate a signature, but do need to know that the 'thing' is signed. This is what the FHIR Signature elements are for. If it wasn't for this need, the Signature datatype would be nothing but a blob (and mime-type).
Alexander Zautke (Jan 12 2019 at 23:41):
Ok, so basically we need to figure out to what level of granularity we want to expose information in FHIR and not having implementers to bother with actually parsing the signature. For a JWS, the mime-type would be "JOSE" or "JOSE+JSON" depending on the serialization form. It's not possible to to indicate that the signature being generate based on an RSA / ECCurve / HMAC key in the "typ" element of a JWS. However, implementers verifying a signature may only support a subset of signature algorithms. For me it would be OK to say that you need to try to parse the signature and if you don't support the algorithm, you would have to skip, but in order to speed things up, it could also be exposed in the signature element.
Alexander Zautke (Jan 12 2019 at 23:45):
Also, I would like to note that under section "3.3.1 Document Content" there is some content that is specific to XML signatures (about linking the key used to sign the document to the attester resource). While in general, I am totally in favour of the content I would like to propose to open it up and make it independent of a signature algorithm.
Alexander Zautke (Jan 12 2019 at 23:47):
Something in the direction of:
"Document Bundles may be signed using digital signatures following the rules laid out in the digital signatures page. The signature SHOULD be provided by a listed attester of the document and the signature SHOULD contain an element linking the key used to sign the document bundle to the attester resource. The fullUri of the matching attester resource SHOULD be used for identification purposes."
Does this make sense?
Last updated: Apr 12 2022 at 19:14 UTC