Hi all,
this is a follow up of a discussion on github [1]
I'm experimenting with an idea of password manager (cli + GUI in Go) that allow to
generate services' password using a pure function and (optionally)
fallback to custom ones where this is not applicable (i.e. imported
passwords).
Neither the user's password nor the private key are stored,
but the last one is used to derive passwords and store some settings
along with the custom passwords into an encrypted file.
The flow is basically:
1. generate private key (pk) from user passprhase with scrypt
2a. generate password for a service (i.e. website) using a fn(hkdf(pk, serviceInfo))
2b. allow user to specify a custom password (i.e. import)
3. store the info and the custom password into a file encrypted using age
The ways I figured out for point 3 are:
- use the user's passprhase or the derived pk as input for an age ScryptIdentity / ScryptRecipient.
This allow to correctly encrypt the file but from the project's UX point of view increase the execution time, we run scrypt twice.
- use the derived pk to generate an ed25519 key from seed and then the agessh Ed25519Identity / Ed25519Recipient
This allow to correctly encrypt the file and reduce the execution time, but make feel me like using age not in the correct way.
- use the derived as input for a age X2519Identity / X25519Recipient
This sounds like the perfect solution for the use case but at the moment is not possible to create X2519Identity using a seed.
Hence the question about the possibility to expose newX25519IdentityFromScalar :-)
I know this is an edge case and probably out of scope for the age's API design since it already allow to encrypt the file in 2 of the 3 points above, but I was thinking worth
to point out anyway ;-)