-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
would the community be willing to accept an AID export feature? #274
Comments
So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I My first reaction is why not just delegate the other keys as the bridge. The other places don’t understand KERI, so they don’t care about the delegation, but anyone who understands KERI can be presented with the delegation of the “other” keys and then verifiy their relattionship to the Signify keys.This way you never violate the principle of don’t move private keys (secrets) between infrastructures. You always create private keys in the infrastructure where they are to be used (ssh etc) and after the fact just bless them with a delegation from your Signify AID. Those delegated keys can be effectively ephemeral by making them non-rotatable in their inception event. The delegated AID can be created after the fact of creating the Ed25519 keys or whateever key pair generation (ECDSAk1,r1).So someone that cares about KERI can verify via the delegated key event that the keysare blessed by the signify AID. But the bridged non keri aware application doesn’t care who blesses the keys.YOu can also bless the keys with an ACDC albeit less securely than delegation.And you can do both. For example you can have a service that is KERI aware that accepts presentations of either ACDC or a delegated public key in order to add it to an SSH server plublic key store of allowed clients. Then a client can login to the SSH server with the private key. The client is just a non-KERI aware client, the blessing happens OOB to the SSH protocol itself.Sent from my iPadOn Aug 30, 2024, at 02:10, Daniel Hardman ***@***.***> wrote:
I am interested in giving Signify an AID export feature (not a whole wallet export feature), where you could ask Signify to look up a particular single-sig AID's current priv+pub keypair and its next public key (the one it's committed to in prerotation), and give them back as raw key values.
Before you say it, I KNOW that giving back private keys is dangerous. It would obviously expose the secrets that are the basis of a given AID (except for the next private key) -- so if the person receiving these secrets manages them in a way that is less secure than Signify does, the trust in the AID could be lowered as a result. We have wallets for a reason...
I also know that if Signify is using keys from an HSM, what I've proposed is impossible; you can't get the keys back at all. You can only get a signature from it. So there would be cases where the feature wouldn't work.
So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I can get an X509 with the public key from my AID. I can also make a did:key and did:peer (and other DID types too, I suppose) from the AID. And I can make other DID types from it, too. And all of those new places where I'm using my key are deriving their security from stuff that's still held in my Signify wallet, so I can think of the AID as being a root of trust for a whole family of derivative identifiers. The KERI ecosystem now has the option of telling people it has support for SSH, for X509, etc. I can also back up the key material in a password manager.
We could possibly reduce the risk of this feature by only exposing it when an AID is created or its keys are rotated, not when it is in a steady state. And we could expose it in a UI only after a consent screen that explains the risks.
If the community is willing to accept such a feature, I would be willing to invest the time to build it. But I don't want to work on it if it will be rejected for security reasons. So I thought I'd ask the question first. What do you think of the general idea?
Tagging @m00sey , @pfeairheller , @SmithSamuelM, @rodolfomiranda
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
The original reason KERI has delegated AIDs was to solve the problem of how do I verifiably distribute my authority across infrastructure without moving private keys. (i.e. solving the distributed authorization problem). Delegation also works nicely with HSM based keys.If you listen to Alan Karp’s presentations on ZCAPs the hard problem of authorization is protecting against thesharing of authorization tokens. Other than forcing the use of HSMs, delegation removes the incentive to share authorization tokens since you share a delegation instead. It protects the delegator and the delegatee. Because you can attenuate the delegates authority and revoke it as needed to protect the delegator not to mention not sharing the delegator’s keys with the delegate which is bad for both since with shared keys they can each repudiate their behavior.Sent from my iPadOn Aug 30, 2024, at 08:06, Samuel Smith ***@***.***> wrote:So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I My first reaction is why not just delegate the other keys as the bridge. The other places don’t understand KERI, so they don’t care about the delegation, but anyone who understands KERI can be presented with the delegation of the “other” keys and then verifiy their relattionship to the Signify keys.This way you never violate the principle of don’t move private keys (secrets) between infrastructures. You always create private keys in the infrastructure where they are to be used (ssh etc) and after the fact just bless them with a delegation from your Signify AID. Those delegated keys can be effectively ephemeral by making them non-rotatable in their inception event. The delegated AID can be created after the fact of creating the Ed25519 keys or whateever key pair generation (ECDSAk1,r1).So someone that cares about KERI can verify via the delegated key event that the keysare blessed by the signify AID. But the bridged non keri aware application doesn’t care who blesses the keys.YOu can also bless the keys with an ACDC albeit less securely than delegation.And you can do both. For example you can have a service that is KERI aware that accepts presentations of either ACDC or a delegated public key in order to add it to an SSH server plublic key store of allowed clients. Then a client can login to the SSH server with the private key. The client is just a non-KERI aware client, the blessing happens OOB to the SSH protocol itself.Sent from my iPadOn Aug 30, 2024, at 02:10, Daniel Hardman ***@***.***> wrote:
I am interested in giving Signify an AID export feature (not a whole wallet export feature), where you could ask Signify to look up a particular single-sig AID's current priv+pub keypair and its next public key (the one it's committed to in prerotation), and give them back as raw key values.
Before you say it, I KNOW that giving back private keys is dangerous. It would obviously expose the secrets that are the basis of a given AID (except for the next private key) -- so if the person receiving these secrets manages them in a way that is less secure than Signify does, the trust in the AID could be lowered as a result. We have wallets for a reason...
I also know that if Signify is using keys from an HSM, what I've proposed is impossible; you can't get the keys back at all. You can only get a signature from it. So there would be cases where the feature wouldn't work.
So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I can get an X509 with the public key from my AID. I can also make a did:key and did:peer (and other DID types too, I suppose) from the AID. And I can make other DID types from it, too. And all of those new places where I'm using my key are deriving their security from stuff that's still held in my Signify wallet, so I can think of the AID as being a root of trust for a whole family of derivative identifiers. The KERI ecosystem now has the option of telling people it has support for SSH, for X509, etc. I can also back up the key material in a password manager.
We could possibly reduce the risk of this feature by only exposing it when an AID is created or its keys are rotated, not when it is in a steady state. And we could expose it in a UI only after a consent screen that explains the risks.
If the community is willing to accept such a feature, I would be willing to invest the time to build it. But I don't want to work on it if it will be rejected for security reasons. So I thought I'd ask the question first. What do you think of the general idea?
Tagging @m00sey , @pfeairheller , @SmithSamuelM, @rodolfomiranda
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
All that said. I get that can be useful for various administrative reasons to export private keys.
So the caveat for me is this. KERI WP and the Universal Identifier Theory WP talk about multivalent key management infrastructure. A useful defintion of valence wrt infrastructure is a given valence (infrastructure) is the set of components that have access to the same secrets in plaintext. This means that the strength of that valence is no stronger than the strength of the weakest component.
This defines a useful boundary as the sharing domains for secrets (salts and private keys).
So if the boundary includes distributed components that are sharing over the internet then one must anticipate the security issues. One of the biggest problems is that while one can share some secrets securely using encryption, it just kicks the can down the road with the fact that encryption requires other secrets to be shared. And DH is repudiable sharing with weak authentication. So a useful boundary for distributed infrastructure within a valence is that given by OOB sharing. So if a person has a secret in their brain then any device they personally physically interact with could be in that valence. But any remote device that they do not personally physicallly interact with is outside that boundary.
… On Aug 30, 2024, at 08:15, Samuel Smith ***@***.***> wrote:
The original reason KERI has delegated AIDs was to solve the problem of how do I verifiably distribute my authority across infrastructure without moving private keys. (i.e. solving the distributed authorization problem). Delegation also works nicely with HSM based keys.If you listen to Alan Karp’s presentations on ZCAPs the hard problem of authorization is protecting against thesharing of authorization tokens. Other than forcing the use of HSMs, delegation removes the incentive to share authorization tokens since you share a delegation instead. It protects the delegator and the delegatee. Because you can attenuate the delegates authority and revoke it as needed to protect the delegator not to mention not sharing the delegator’s keys with the delegate which is bad for both since with shared keys they can each repudiate their behavior.Sent from my iPadOn Aug 30, 2024, at 08:06, Samuel Smith ***@***.***> wrote:So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I My first reaction is why not just delegate the other keys as the bridge. The other places don’t understand KERI, so they don’t care about the delegation, but anyone who understands KERI can be presented with the delegation of the “other” keys and then verifiy their relattionship to the Signify keys.This way you never violate the principle of don’t move private keys (secrets) between infrastructures. You always create private keys in the infrastructure where they are to be used (ssh etc) and after the fact just bless them with a delegation from your Signify AID. Those delegated keys can be effectively ephemeral by making them non-rotatable in their inception event. The delegated AID can be created after the fact of creating the Ed25519 keys or whateever key pair generation (ECDSAk1,r1).So someone that cares about KERI can verify via the delegated key event that the keysare blessed by the signify AID. But the bridged non keri aware application doesn’t care who blesses the keys.YOu can also bless the keys with an ACDC albeit less securely than delegation.And you can do both. For example you can have a service that is KERI aware that accepts presentations of either ACDC or a delegated public key in order to add it to an SSH server plublic key store of allowed clients. Then a client can login to the SSH server with the private key. The client is just a non-KERI aware client, the blessing happens OOB to the SSH protocol itself.Sent from my iPadOn Aug 30, 2024, at 02:10, Daniel Hardman ***@***.***> wrote:
I am interested in giving Signify an AID export feature (not a whole wallet export feature), where you could ask Signify to look up a particular single-sig AID's current priv+pub keypair and its next public key (the one it's committed to in prerotation), and give them back as raw key values.
Before you say it, I KNOW that giving back private keys is dangerous. It would obviously expose the secrets that are the basis of a given AID (except for the next private key) -- so if the person receiving these secrets manages them in a way that is less secure than Signify does, the trust in the AID could be lowered as a result. We have wallets for a reason...
I also know that if Signify is using keys from an HSM, what I've proposed is impossible; you can't get the keys back at all. You can only get a signature from it. So there would be cases where the feature wouldn't work.
So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I can get an X509 with the public key from my AID. I can also make a did:key and did:peer (and other DID types too, I suppose) from the AID. And I can make other DID types from it, too. And all of those new places where I'm using my key are deriving their security from stuff that's still held in my Signify wallet, so I can think of the AID as being a root of trust for a whole family of derivative identifiers. The KERI ecosystem now has the option of telling people it has support for SSH, for X509, etc. I can also back up the key material in a password manager.
We could possibly reduce the risk of this feature by only exposing it when an AID is created or its keys are rotated, not when it is in a steady state. And we could expose it in a UI only after a consent screen that explains the risks.
If the community is willing to accept such a feature, I would be willing to invest the time to build it. But I don't want to work on it if it will be rejected for security reasons. So I thought I'd ask the question first. What do you think of the general idea?
Tagging @m00sey , @pfeairheller , @SmithSamuelM, @rodolfomiranda
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
—
Reply to this email directly, view it on GitHub <#274 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAETEPMG2FUVNUJ5OW64L7LZUB5BHAVCNFSM6AAAAABNL7DG6KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMRRGQYDEOBWGA>.
You are receiving this because you are subscribed to this thread.
|
Two questions come to mind, @dhh1128:
|
@SmithSamuelM said:
This sounds cool, but I am not aware of a way to delegate to pure keys. AFAIK, the only way to delegate in KERI is cooperative delegation, which requires an AID on the receiving/delegatee side. Is there a way to inject an existing key pair (the pub part, I mean) into the routine that generates a delegated AID? If so, it could well address most of my intent, and I'd love to learn about it! @edeykholt said:
Yes, this is pretty much what I need. Except I don't want a Signify client to provide it. I want to bring the pub key to KERI and have KERI delegate to it. But I don't know a way to do that.
I think we can write a feature that moves a wallet from one KERIA instance to another. But not a feature that moves individual AIDs. |
This functionality of moving keys around is not really part of KERI. It just so happens that keripy includes a key store and key store manager in the keri.app.keeping module. The Manager class has a method called .replay and one called .ingest that will allow one to export i.e. replay the key history for a given AID and then import i.e ingest a key history created someplace else. Although replay only replays the public keys. to actually export the private keys requires writing a private key export function that uses the public key replay to look up and decrypt the private key and then export it. We didn't implement this because its generally a bad idea but given you do that the ingest method can import the private keys. the Hab.make method already optionally allows one to ingest a key history into its associated key manager and then replay the key at the current key state so that one can then lookup and get the private keys to sign as needed.. There is a lot of functionality in the keeping module that very few know about because its not part of the KERI protocol but was created to enable basic wallet functionality in keripy. |
@dhh1128 The key manager keri.app.keeping.Manager can ingest private keys created elsewhere. So after the fact you can spin up a Manager and a Hab which Hab looks up the public key from the Manger so that the Hab tha can create the incept message that generates the AID for any set of private keys the Manager has already ingested. So you don't need to know the AID of the delegate until after the fact. So you can decide to delegate after the fact and create the delegated AID on the fly given you already have the key pairs to ingest. The point of the delegation is to enable some user to authentically attribute that the private keys that after the fact generated the delegated aid, were indeed blessed. So you can build the bridge afterwards you don't have to spin up a wallet to use the private keys. You can at any time spin up a wallet in the infrastructure that created the key pairs, ingest the key pairs, and then cooperatively delegate them via the resultant aid. |
So for example I can take my ledger nano create keys pairs use them to sign up etc and then later export the public keys to create an aid sign it with the ledger nano, publish it and then have it cooperatively delegated all after the fact of using those private keys via the nano. The nano never needs to know it is being used for KERI. So this is a bridge that backfills when an only when you need the backfill. |
The typical use case for the Keripy keeping.Manager is to NOT create and store private keys directly but to use a salt and an HKKey algorthm to generate the private keys on the fly from a public HDKey path. So moving private keys between infrastructures never happens. One moves the salt out-of-band and the public HKKey path in band. Moving the salt is easily accomplished by using something like 1password. So we really don't in general need to export anything other than the HDKey path, which actually for an existing KEL can be generated from the KEL itself (just the sn and rotation index of the public key history). So if you are generating and storing private keys someplace not using an HDKey mechanism then you basically have private key material you can import after the fact. If on the other hadn your are using an HSM that doesn't allow you to export the salt then you can't import the private key material anyway so you have to always move the HSM from device to device. In either case, private key material never ever needs to be exported from a KERI wallet only imported to a KERI wallet. The main reason not to use an salt with and hdkey algorithm inside a KERI wallet to generate private keys is because you believe that the an Hdkey algorithm is not secure enough. In that case you would never want to export the private keys because that defeats the whole point of not using an hdkey algorithm in the first place. The manager supports both, but in general NON hdkeys would be imported from some place else not created. And if they can be imported from someplace else then they already exist outside the KERI wallet and therefore don't need to be exported to move them to another wallet. If they exist outside, then they would most likely alreaddy be stored encrypted and so you have already had to solve the kick the can problem of the encryption keys independently so there is no benefit to resolving that problem just reuse the outside mechanism to reimport to multiple keri wallets. |
By the way, using KELs that contribute to a distributed multisig takes advantage of the fact that the key state of the contributing keys can be regenerated from the salt and HDKey path derived from the contributing KEL. So, the key manager doesn't need a different construct to support HDKeys for distributed multisig groups. If a given controller contributes keys from one of its own KELs then all the key manager has to track is its contributing KEL and the associated salt. It can regenerate the private key it needs to sign the group multisig messages from its contributed public key. and it can find where in its own contributed aid key history that contributed public key was used to get the HDpath if need be. |
So back to the original question: I assumed that if there is an application outside of KERI that needs private key material, then that application already has a way to generate that private key material. So KERI just needs to import it and bless it via delegation. If that outside application does not already have a way to generate private key material then I strongly suggest that one use an HDKey generation algorithm with a secure Salt. The Salt can be created, stored, and moved between infrastructure using 1password, so no need to reinvent that wheel. So whats left to do. Implement an HDkey generation algorithm externally and track the HDKey path. If you want to use a KERI wallet for that, you can do that using the keeping.Manager with a non digest temporary AID that is just the fully qualified first public key. Ie. the aid is the first public key. You can move that key history to some other aid later using keeping.Manager.move Now you can just track the keys and all you have is a placeholder aid. No KEL. At some time later you can create a real AID and KEL and assign (move) that key history in the the manager to that AID. It creates a forward index so one can track where it got moved to given the original placeholder aid. Now you don't ever have to export private keys, just move the salt to some local application that can run the HDKey algorithm to regenerate the keys. This can just an application that is not KERI but just the keeping.Manager . The manager has a .sign method that lookups or regenerates the private keys and signs. This is how keriPy signs anything under the hood the Manager signs. So all you need is the keeping Module to implement a non-KERI wallet key generation storage and signing. The keeping.Manager HDKey path is designed such that its compatible with a KEL, so all you need is the Salt and a KEL and one can regenerate the path from the KEL. Or if you have the Manager then the path tracks a virtual KEL without needing a KEL because when you Manager.rotate it generates keys to match the HDKey algorthm that maps to the virtual KEL's key state that would have been created with that key rotation. You can then after the fact assign that key history to a real KEL and the AID is only generated after the fact (since the key history just uses a placeholder AID until you explicitly move it to some other aid. If its an ephermeral AID then you just need to manager.incept to create the key history path for the initial key and assign it to the placeholder AID. You can then move it to some other AID later. keeping.manager does not understand anything about KERI key events only key histories that follow a KEL compatible key generation algorthim. keri.app.keeping is 1768 lines of python code including comments doc strings and white space. It imports several cesr (Matter subclasses) for seeds, salts, digests, etc. So not a big port. It has its own dedicated lmdb (not shared with the KEL lmdb). So it can be run as a standalone application that just manages key histories. This functionality was by design and has been there for several years now. |
In the beginning was Key State and KERI was not. But the Key State was good so KERI was created to divide the Key State into verifiable events and it was good. |
One more thought. As I outlined above, exporting private keys means simple adding an export function to the keeping.Manager in keripy so its easy. Whereas creating a standalone application to regenerate keys from the same salt, i.e. not exporting them. Is more work. The risk here is that once people take the easy path of exporting private keys, the tendency (very real) is to create fragile weak key mangement infrastructure because exporting private keys makes them shared secrets not truly private keys anymore and then build applications that depend on such shared secret infrastructure. This is how we got into the shared secret insecurity that comes from attempting to manage a multiplicity of shared secrets that is endemic of the web now. |
What many don't appreciate it is that 1password follows best practices for managing secrets so one can use it to manage salts for HDKeys. 1password uses slow hashing 0.25 seconds so that any reasonable length password used to unlock 1password can't be brute forced in any reasonable amount of time. Likewise keripys keeping stretch algorithm uses slow hashing via the Argon2 algorithm that when set to the highest tier can take a long time to generate a key from a salt so guessing a salt to get a known key is not brute forceable. So, basically, by not having any shared secrets, the attack vector is to get you to voluntarily unlock your 1 password or to intercept your salt when you copy it from 1password to unlock your Keri key store. But as soon as we enable exporting private keys, the attack vectors multiply without bounds. |
KERIA doen't have the private keys. Only the Signify client has them unencrypted, and it can potentially use them with different KERIA providers |
We discussed on the community call on 10 Sep 2024, and agreed that we could achieve the goal without the suboptimal choice of exporting private keys. Fundamentally, we import the keys to KERI rather than creating them in KERI and exporting them. @SmithSamuelM shared that in a habery's make() method, it is possible to pass a We also explored how to combine this with what Signify is doing. @pfeairheller pointed out that Signify already supports 3 AID creation methods (random, salt, HSM). We could add a 4th method that creates an AID from pre-existing keys, and then have Signify-TS just prompt for a privkey whenever it is needed. I'm going to close this issue as resolved. |
I am interested in giving Signify an AID export feature (not a whole wallet export feature), where you could ask Signify to look up a particular single-sig AID's current priv+pub keypair and its next public key (the one it's committed to in prerotation), and give them back as raw key values.
Before you say it, I KNOW that giving back private keys is dangerous. It would obviously expose the secrets that are the basis of a given AID (except for the next private key) -- so if the person receiving these secrets manages them in a way that is less secure than Signify does, the trust in the AID could be lowered as a result. We have wallets for a reason...
I also know that if Signify is using keys from an HSM, what I've proposed is impossible; you can't get the keys back at all. You can only get a signature from it. So there would be cases where the feature wouldn't work.
So why do I want this? Well, because if I have the keys, I can build bridges to places that know nothing about KERI (yet), but that do understand Ed25519 keys. There are lots of places like that. For example, I can make an SSH key that I use to log in to servers or my github account. I can sign stuff with ssh-keygen. I can get an X509 with the public key from my AID. I can also make a did:key and did:peer (and other DID types too, I suppose) from the AID. And I can make other DID types from it, too. And all of those new places where I'm using my key are deriving their security from stuff that's still held in my Signify wallet, so I can think of the AID as being a root of trust for a whole family of derivative identifiers. The KERI ecosystem now has the option of telling people it has support for SSH, for X509, etc. I can also back up the key material in a password manager.
We could possibly reduce the risk of this feature by only exposing it when an AID is created or its keys are rotated, not when it is in a steady state. And we could expose it in a UI only after a consent screen that explains the risks.
If the community is willing to accept such a feature, I would be willing to invest the time to build it. But I don't want to work on it if it will be rejected for security reasons. So I thought I'd ask the question first. What do you think of the general idea?
Tagging @m00sey , @pfeairheller , @SmithSamuelM, @rodolfomiranda
The text was updated successfully, but these errors were encountered: