De-duplication of unsigned data when requesting multiple credentials.

Issue #2003 resolved
Jacob Ward created an issue

Situation:

To prevent relying party collusion and thereby improve user privacy, an issuing authority wants to provide multiple one-time use copies of a credential to a wallet, each bound to a different keypair in the wallet. Unfortunately some of the claims in the credential are very large, for example a user portrait image, so simply using the batch credential endpoint would result in a needlessly large response size due to duplicated claims. The credential format is an “sd-cred”, similar to an sd-jwt or mdoc, where the unblinded claims could be transmitted separate from the signed credential.

A secondary issue, is that the issuing authority needs a mechanism through which to inform the wallet of how many copies of the credential it should request.

Possible solutions:

I have though of three possible solutions to the main issue:

  • Requiring no changes to the specification, two credential formats identifiers could be defined: “sd-cred” and “sd-cred-claimless”. The wallet can request one “sd-cred” and many “sd-cred-claimless” using the batch credential endpoint, and only receive the unblinded claims in the “sd-cred” response. The wallet should treat the unblinded claims from the “sd-cred” response as the unblinded claims for all “sd-cred-claimless” credentials received in the response.

  • Requiring no changes to the specification, a new credential format identifier “sd-cred” could add an additional “non-core” parameters to the credential request structure, for example:
    The following additional parameter is defined for Credential Requests and this Credential format.

    • extra-proofs: OPTIONAL. A JSON array of addition proof objects of wallet-bound public keys to which should be issued “claimless” credentials.

  • Requiring no changes to the specification, a new proof type “jwts-claimless” could be defined for use with the “sd-cred” credential format identifier:

    The following proof type is defined for use in Credential Requests and this Credential format.

    • jwts-claimless: objects of this type contain a single jwts element which is a JSON array of JWTs as defined in Section 7.2.1 of OID4CI.

In the last two cases the batch of credentials should all be encoded in a single credential field, as defined for this credential format identifier.

I believe the secondary issue can be easily resolved through defining a new field in the issuer metadata for that credential format.

Please let me know which of any of these solutions are suitable for use with OID4CI, or if there are better ways forwards.

Comments (13)

  1. Kristina Yasuda

    Before getting into the protocol mechanics, a fundamental question I have is… For both mdocs and SD-JWTs, how does changing only the DeviceKey to which a credential is bound, without changing the randoms/salts for each data element/claim helps “prevent relying party collusion”? For both mdocs and sd-jwts, issuer sign over the digest that is a hash over both random value and the actual claim value. If this random value stays the same, that results in the same hashes in the MSOs/JWS and becomes a correlation factor. If this random value needs to be communicated, I don’t see much value in duplicating only the issuer-signed parts because for each issuer-signed parts, the combination of random values to the plain text claim value also needs to be communicated, in which case, issuing multiple entire credentials sounds simpler… (though I understand portrait images are huge.)

    jfyi tThis is the input for the Digest in MSO

    IssuerSignedItem = {

    "digestID" : uint, ; Digest ID for issuer data authentication

    "random" : bstr, ; Random value for issuer data authentication

    "elementIdentifier" : DataElementIdentifier, ; Data element identifier

    "elementValue" : DataElementValue ; Data element value

    }

    cc @Daniel Fett @Brian Campbell

  2. Jacob Ward reporter

    Thank you for your comment Kristina.

    how does changing only the DeviceKey to which a credential is bound, without changing the randoms/salts for each data element/claim helps “prevent relying party collusion”?

    the combination of random values to the plain text claim value also needs to be communicated

    A couple of small corrections here:

    • The salts would be different for each credential.
    • The combination of salts to plain text claim identifier need to be communicated.

    Using mdoc as an example, to send a “full” credential the issuer would need to send:

    • Signed credential
    • Mapping of element identifier to:

      • digest id
      • salt
      • element value

    To send a “dehydrated” credential the issuer would need to send:

    • Signed credential
    • Mapping of element identifier to:

      • digest id
      • salt

    The only difference between the two is that the “full” credential response would contain the element values. The digest IDs and salt would be different for each credential.

    issuing multiple entire credentials sounds simpler

    It may be simpler but it doesn’t address the issue.

    I would appreciate if you could also comment on the secondary issue - how should the issuer communicate to the wallet the number of credential copies that it should request? Is my suggestion of including it in credential format specific Issuer Metadata a good idea?

  3. Kristina Yasuda

    SIOP Aug-10-2023 call

    Mark Haine mentioned work in ekyc-ida that might be relevant openid / ekyc-ida / Pull Request #169: Move attachments to a separate document — Bitbucket

    we discussed that the options chose will not have impact on how the response is encrypted because the entire response will one or more credentials issued is entirely encrypted as JWE.

    we discussed that the same mechanism should apply to both credential and batch credential endpoints.

    Kristina expressed the preference to define a new credential format that signals issuance of “dehydrated” credential because the wallet needs to know what it is receiving and that is not straightforward when only proof is modified like in two other proposals.

  4. Kristina Yasuda

    @Jacob, follow up question on the actions required for the holder and the verifier for “dehydrated” credential.

    when the holder receives the credential, it will have to receive one full credential and multiple dehydrated credentials. assuming that the fact that the issuer signs over the claim value too, when the wallet sends a credential to the to verifier, the wallet will have to reproduce digest id, salt, element value combination based on full credential and dehydrated credentials, correct? that’s a lot…

  5. Kristina Yasuda

    I have been thinking about this a litte, and I think the simplest way to do this with mdoc and sd-jwt is to define a string (“dehydrated” for example) that goes instead of a plaintext claim value in a dehydrated credential. this might or might not have an impact on the protocol side. on one hand, it would be easier to negotiate between wallet and the issuer if there is a new format identifier for dehydrated, but on the other hand, it is pretty much still the same credential format from a structural perspective, so if the issuer knows the wallet supports dehydrated credentials, it actually might just issue dehydrated ones in response to the same 1mso_mdoc credential format requests.

  6. Daniel Fett

    We do have a discussion on this in SD-JWT, see https://github.com/oauth-wg/oauth-selective-disclosure-jwt/issues/329

    My impression is that such a ‘dehydrated’ credential or similar techniques are just highly specialized compression algorithms. So why not use GZIP?

    GZIP’ing HTTP requests is already a default today.

    At least for SD-JWT, bunches of similar credentials will be highly compressable. At most there should be three copies of any large data field (when the bytes are not aligned in the base64 representations), but with simple optimizations (using the same order of fields and same byte lengths for keys and nonces), the issuer can bring that down to exactly one copy. Bonus feature: All your other data fields will be compressed as well.

    GZIP can be applied not only for transfer, but also for storage.

    Compared to any of the proposed solutions above, at least the transport part should be extremely easy to implement. The storage part may be a bit more complex, but it’s not rocket science either.

    (Replace GZIP above by your favorite algorithm.)

  7. Jacob Ward reporter

    Thanks Daniel, that’s a good point. It doesn’t cover all cases however, such as when the issuer is just issuing a new credential(s) without any updates to the claims – in that case it would want to only send dehydrated credentials.

  8. Log in to comment