[tor-dev] Safe Alternative Uses of Onion Service Keys

Nick Mathewson nickm at freehaven.net
Mon Aug 10 13:09:19 UTC 2020

but it's trivial to verify the certificate if you know what the

On Mon, Aug 10, 2020 at 9:00 AM Nick Mathewson <nickm at freehaven.net> wrote:
> On Wed, Jul 29, 2020 at 1:15 AM Matthew Finkel <sysrqb at torproject.org> wrote:
> >
> > Hello everyone,
> Hi, Matt!
> There's a part of this that I'm still trying to figure out:
> > The safest usage of the long-term keys for alternative purposes I see
> > appears to be by deriving a (fixed/deterministic) blinded key pair using
> > the same scheme that Tor uses, and signing/verification simply follow
> > the same process as Tor, except the derived keys need not rotate
> > periodically (is this true?). The derived key should be used for
> > certifying a freshly generated ed25519 key, which is used in the
> > application protocol. For example, if I want to use a key for code
> > signing such that it is bound to my onion service key, then I could
> > derive a certifying key by following Tor's derivation scheme, by
> > substituting:
> >
> >   BLIND_STRING = "Derive temporary signing key" | INT_1(0)
> >   N = "key-blind" | INT_8(period-number) | INT_8(period_length)
> >
> > with
> >
> >   BLIND_STRING = "Derive code signing key" | INT_1(0)
> >   N = "code-sigining-key-blind" | "v0" | "YYYY-MM-DD" |  INT_8(validity_period)
> In the case of v3 onion services, 'period-number' comes from the
> current time, and 'period-length' comes from the consensus, so it's
> easy for the client to know what parameters to use when deriving the
> key.
> But how is the party that relies on the derived key supposed to know
> what values were used for "YYYY-MM-DD" and "validity period" in this
> case?  It seems like those two values would need to be shipped along
> with the key, which could make for logistical issues.
> I guess in the case of an X.509 certificate, we could use the
> validAfter  and validUntil fields to set the  parameters -- though
> it's a little weird to have to look at _just_ those fields to see what
> the signing key is supposed to be.
> Maybe, for an X.509 cert, we could have
>   N = "x509 onion key derivation" | H(unsigned-certificate)
> where `unsigned-certificate` is a DER-encoded TBSCertificate (the part
> of the certificate that's signed).  That way, we get a separate
> blinded key for each certificate.
>  [...]
> > The above process seems like a lot to ask from application developers.
> > Can we make it easier for them?
> >
> > Open questions:
> >
> >  1) Going back to the long-term secret key, can LH and RH be used
> >     directly in EdDSA without reducing the security and unlinkability of
> >     the blinded keys?
> From a practical point of view: Forcing the signer to keep LH and RH
> online reduces the security of the protocol IMO; the current protocol
> is designed so that the onion service doesn't need to keep its
> long-term identity key online.
> Also note that if we care about keeping the primary identity key
> offline, LH' and RH' shouldn't be used directly!  Although it is not
> possible to derive a long-term public key from a blinded public key,
> it IS possible to derive a long-term _private_ key from a blined
> private key.  That's why in the v3 onion service system, blinded
> private keys aren't kept for any longer than needed in order to
> certify a short-term randomly generated signing key.
> >  2) Should other use cases of the long-term keys only derive distinct
> >     (blinded) keys, instead of using the long-term keys directly?
> IMO yes.
> >  3) If other use cases should only use derived keys, then is there an
> >     alternative derivation scheme for when unlinkability between derived
> >     keys is not needed (without reducing the security properties of the
> >     onion service blinded keys), and is allowing linkability
> >     useful/worthwhile?
> >
> >  4) Is the above example derivation scheme safe if different
> >     applications tweak the above prefix strings in similar ways?
> >
> >  5) Should Tor simply derive one blinded key that can be used by all
> >     alternative applications? Is that safe?
> Yes, but only if that key will never ever need to rotate.
> Here's a suggestion -- what if we come up with a single profile for
> this kind of key derivation, to be used in X.509.  Along with it, we
> could have a nice small library that can generate and verify the
> "root" certificates (the ones signed by a blinded key).
> What important parts of the application space would be left unaddressed by that?

Like, here's the API I'm envisioning, in pseudocode.

On the service side, you would have a function that takes the primary
keypair for an onion service, and an unsigned X.509 certificate, and
produces a signed certificate:

  X509Cert create_cert(PrimaryKeypair, UnsignedCertificate);

then later on, an application that knows the public key for an onion
service could check one of these certificates by getting the public
key as follows:

  PublicKey get_public_key_to_check_cert(X509Cert, PrimaryPublicKey pub);

and then the application would just call the regular X509 verification


Of course, maybe we'd want to stick the blinded signing key in the
certificate, so that you could verify the certificate without knowing
its identity key?  If so we'd need a different API to create the cert,
but we could still make it work.


More information about the tor-dev mailing list