-
I would like to export the private key as an array of bytes and then import that into another private key. For this specific usecase, I would need an array of bytes, not an ascii-armored string. Additionally, I would want this array of bytes to be small, preferably under length 64 (which is why I cannot just convert the ascii-armored string to bytes). And, I want to be able to both export from a key and import this to create the identical key later. Is this possible within openpgpjs? I have a feeling that it's somewhere in the |
Beta Was this translation helpful? Give feedback.
Replies: 16 comments 4 replies
-
Here's a snippet we use. It would be good to have this in the library 👍 public static dearmor = async (text: string): Promise<{ type: OpenPGP.enums.armor, data: Uint8Array }> => {
const decoded = await opgp.armor.decode(text);
const data = await Stream.readToEnd(decoded.data);
return { type: decoded.type, data };
} |
Beta Was this translation helpful? Give feedback.
-
Ah, interesting, this is helpful... but I don't want to just convert the ascii-armored string to bytes. I would like a bytes array of under length 64. I guess that this would be the initial derivation bytes used to derive the key. I was thinking this might be the |
Beta Was this translation helpful? Give feedback.
-
I didn't read your whole message. I was just referring to exporting it as unarmored bytes, nothing else. Sorry for confusion. |
Beta Was this translation helpful? Give feedback.
-
@twiss Do you know a solution? Is |
Beta Was this translation helpful? Give feedback.
-
@larabr @twiss Any updates on whether |
Beta Was this translation helpful? Give feedback.
-
Hey @CMEONE 👋 No, this isn't really possible, sorry. For one, to encrypt or decrypt messages, you also need the subkey material. Then, for it to be the same OpenPGP key, you also need a bunch of metadata (creation time, etc). If you want something short, it might be better to use a raw ECDH key. E.g. see https://github.com/dchest/tweetnacl-js. Obviously this won't be compatible with OpenPGP, though. |
Beta Was this translation helpful? Give feedback.
-
@twiss Ah, I see. Will there be any sort of deterministic key generation in the future (besides loading an armored private key), perhaps in v6 or later? Something like 12 word / 24 word seed phrases to load in a key (similar to how cryptocurrencies work)? I mean I can allow users to create a backup using a keyfile which stores the armored private key, but from a UX perspective, I would prefer the 12/24 word seed phrase approach (using a length 2048 words list as described in BIP39). I prefer PGP over NaCl, is it possible to do any sort of deterministic keygen through OpenPGP.js, or will that be added sometime in the future? If not, any way to manually create these keys with lossy conversion (I'm totally fine losing metadata such as userids or creation time and just upon key generation, regenerating with the lossy version)? |
Beta Was this translation helpful? Give feedback.
-
No, nothing like this is planned, sorry. You could offer to host the key encrypted (on the client) with the seed phrase or a key derived from that, and allow them to download and decrypt it when they want to retrieve their data. |
Beta Was this translation helpful? Give feedback.
-
Right, my plan was to offer hosted encrypted backup on the server or just give them the encrypted keyfile containing the armored private key. I was just wondering if high-entropy brainwallet was possible with this lib or would be possible at some point is all. |
Beta Was this translation helpful? Give feedback.
-
Hey @twiss, just wanted to follow up here because I had a different idea. By looking through the |
Beta Was this translation helpful? Give feedback.
-
Maybe, but you do you have to pass the metadata (creation time, user ids, etc) for OpenPGP.js to consider it a valid key.
Could you elaborate on this? It sounds like PGP is not the right tool for the job you want to do, tbh. |
Beta Was this translation helpful? Give feedback.
-
@twiss I can pass in a dummy creation time or user ids or store that data on server, but I preferably do not want the server ever touching the private key (encrypted or not). I also want to make it easy for someone to backup, with a 12 word or 24 word phrase. The phrase can be randomly generated based on I'd prefer using PGP, I can use NaCl and that's not an issue but I'd much rather use PGP since I'm more comfortable with it. NaCl is newer, and I'm not as familiar with it. Since I'm working with cryptography, I'd better be dead sure I'm doing everything right. |
Beta Was this translation helpful? Give feedback.
-
Hmhm, I understand. However - are you planning to encrypt files with this key-derived-from-words, and store those on the server? If so, it means you're trusting the encryption. Adding an extra intermediary step (encrypting them with a key which you encrypt with the bip39 mnemonic) doesn't meaningfully reduce the security, and makes it easier to change the mnemonic, if needed.
IMHO, you're more likely mess something up when (ab)using PGP in a weird way, than using NaCl in the normal way. In either case, getting it reviewed by a cryptographer would be ideal. Even when using an integrated solution such as PGP, it's possible to mess up the security of the application. |
Beta Was this translation helpful? Give feedback.
-
@twiss Ok, looks like NaCl might be better suited for what I'm trying to do. I'll look into the repo you posted earlier. Thanks so much for your help! |
Beta Was this translation helpful? Give feedback.
-
No problem, good luck! |
Beta Was this translation helpful? Give feedback.
-
@CMEONE Were you able to get this to work somehow, or did you abandon the idea? I opened a related discussion, here a summary:
See full post here: #1309 It looks like BIP85 defines how the metadata has to be handled (eg. creation timestamp), addressing the concerns of @twiss. BIP85 is still a fairly new standard, but it is slowly gaining adoption in the cryptocurrency world. The use case I had in mind sounds similar to what @CMEONE wanted to do. Basically, it would allow you to deterministically generate a PGP key using your mnemonic. The big advantage of this is that you ONLY have to securely back up your seed, (eg. using Shamir's Secret Sharing), you don't have to worry about backing up anything else. As @twiss pointed out, one option would also be to simply generate a new keypair, encrypt it using the mnemonic and then backing it up to a server. While I would personally prefer if none of my secrets ever touched the internet, security wise, there is no issue with this approach. However, it does provide worse UX than deriving the keypair directly from the mnemonic. The user now additionally has to transfer the encrypted key out of the secure device, back it up and make sure he doesn't lose access to it. Whereas with the first approach, you could have a simple button that would generate a new PGP key that the user can always recover if he has to. Besides the fact that it is currently not possible in openpgpjs or with webcrypto, is there anything wrong with this approach? Are there any easy "workarounds" that could be used for a proof-of-concept in a non-production environment? As to the question why PGP instead of NaCl: One thing I would like to do is allow users to use our offline app (AirGap Vault) to sign git commits in an air-gapped fashion while their key is on an offline device. And as far as I understand, for that, the user needs a PGP/GPG key. |
Beta Was this translation helpful? Give feedback.
Hey @CMEONE 👋 No, this isn't really possible, sorry. For one, to encrypt or decrypt messages, you also need the subkey material. Then, for it to be the same OpenPGP key, you also need a bunch of metadata (creation time, etc). If you want something short, it might be better to use a raw ECDH key. E.g. see https://github.com/dchest/tweetnacl-js. Obviously this won't be compatible with OpenPGP, though.