Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Ali Cherry
    @alichry
    I am working on an Open Source project and would like the user to select a specific subkey, I believe it might be relevant as the user might create an additional subkey just for this purpose
    Daniel Huigens
    @twiss
    Hmhm. In my opinion, selecting the subkeys should be an implementation detail, and not left to the user
    There may be other considerations, such as, a subkey may be expired, or not valid yet
    If the user wants to use different keys for different purposes, they should probably generate separate master keys, IMHO
    Ali Cherry
    @alichry

    How about we specify a specific keyId that is optional in openpgp.encrypt? The underlying function that returns the latest valid encryption subkey can also try to match it against a keyId, just like the current implementation that accepts an optional keyId parameters in many functions to return a specific keyId? I would be happy to start working on this, if you think it's feasible to implement

    Moreover, I understand the reasoning to create a separate OpenPGP key for a different purpose. But I believe having different PGP keys for different purposes adds complexity for the user to keep track of various primary keys. If I am not mistaken, GnuPG allows for encryption of data by specifying a desired subkey which is why this calls for OpenPGP.js to be compatible with the existing conventions

    I am not certain if this is sufficient to make it work: openpgpjs/openpgpjs#1203
    Daniel Huigens
    @twiss

    How about we specify a specific keyId that is optional in openpgp.encrypt? The underlying function that returns the latest valid encryption subkey can also try to match it against a keyId, just like the current implementation that accepts an optional keyId parameters in many functions to return a specific keyId? I would be happy to start working on this, if you think it's feasible to implement

    Hmm, yeah, we could do that :+1: However, we've done a major refactoring in the v5 branch, could you implement it there, instead? There are also many API changes in the v5 branch, that are documented here: https://github.com/openpgpjs/openpgpjs/wiki/V5-Changelog. Implementing it in v5 avoids us having to rebase the v5 branch on top of your changes, or the other way around.

    I am not certain if this is sufficient to make it work: openpgpjs/openpgpjs#1203

    I don't think this would be sufficient, as there is a lot of code beyond that that assumes that we have a full OpenPGP key, and we probably want to keep requiring a valid OpenPGP key, anyway.

    Ali Cherry
    @alichry
    Lovely, thank you for the chat! Very excited to work on the v5 branch
    Daniel Huigens
    @twiss
    Great, thanks as well! Good luck, and lmk if you have any questions :blush:
    will Farrell
    @willfarrell
    Hi, is it possible to sign/verify by passing in the hashAlgorithm/checksum instead of a message? When the digest is known, there is no need to re-calculate it, especially on larger files. Digging into the code, it looks like it is supported, but not exposed. https://github.com/openpgpjs/openpgpjs/blob/master/src/crypto/public_key/elliptic/ecdsa.js#L76
    Daniel Huigens
    @twiss
    Hi @willfarrell :wave:
    For verifying, there may be some way to hack this together, by setting signaturePacket.hashed, and then calling signaturePacket.verify() directly (perhaps with streaming = true, to dissuade it from reading the data directly).
    However, please keep in mind that OpenPGP signatures include some additional metadata into the hash, such as the signature creation time. So if you only know the hash of the file itself, that may not be sufficient.
    will Farrell
    @willfarrell

    @twiss Thank you for the quick reply. I'll take a closer look intosignaturePacket and how I might be able to trick into signing/verifying. That's really good to know that additional metadata is included inside the hash, I'll look in the codebase for how that's applied. That would mean the hash of a file from openpgp wound not match the hash from openssl/shasum/etc, is that right? If so, that would mean when someone verified the detached signature (w/o metadata hashed) not using our system it wouldn't verify.

    

A little background for context; I work on an open data portal (datastream.org) where we currently validate the data schema and creating a digest in web workers during an upload process. This digest is later added to a public ledger (Eth mainnet) for proof of integrity. We're investigating what it could look like to sign the data before the upload starts. Currently i'm imaging the contributor would be given the option to sign after no errors were found in the data schema. Our community is very non-technical, and the files can be multi-GB in size.

    Daniel Huigens
    @twiss

    Yes, correct.

    If you want, you could just sign the hash (as an openpgp message, e.g. using openpgp.message.fromBinary()). Then of course openpgp.js will hash the hash again during signing, but that's a relatively cheap operation.

    will Farrell
    @willfarrell
    Yeah, I was thinking that. But might require extra documentation and steps for those to verify on their own machines. A change in user workflow will be needed to simplify this case, something to relfect on. Thank you for your assitence on this, it's been very helpful. Have a wonderful weekend.
    Kevin Moutet
    @sinderw
    Hi, I don't know if this is the correct place to talk about the openpgp.d.ts file? It is lacking Key.toPacketlist in v5.0.0-1
    Daniel Huigens
    @twiss
    Hi @sinderw :wave: Yeah, this is a fine place to ask, however, if you don't mind me asking, what do you need toPacketListfor? It's kind of considered an internal / private function, which is why it's not exported in openpgp.d.ts.
    Kevin Moutet
    @sinderw
    I use it to export keys as binary (Key.toPacketlist().write()) and import them back with readKey({binaryKey: ...}). Is that a mistake? Other classes like Message and Signature have a public packets member
    Daniel Huigens
    @twiss
    Oh, I see. No, that's fine. But probably we should add a key.write() (and message.write(), etc) function for this, and export that, instead
    Kevin Moutet
    @sinderw
    Thanks, do you want me to do something about it, like creating an issue to follow it?
    Daniel Huigens
    @twiss
    Yes, that'd be great :blush: If you feel like, a PR would also be welcome
    Kevin Moutet
    @sinderw
    Sure, I'll work on it! :)
    Daniel Huigens
    @twiss
    Thanks! :D
    saurabh-pawar96
    @saurabh-pawar96

    Hello,
    Can I get some help with an issue I am currently facing?
    Im using openpgp version 4.10.10 with Node (12.21.0)
    This is the code used to encrypt and sign a file

    const zippedFile = './ZipFile.zip';
    const publicKey = fs.readFileSync(process.env.ENCRYPTION_PUBLIC_KEY_PATH, 'utf8');
    const signingPrivateKey = fs.readFileSync(process.env.PGP_PRIVATE_KEY_PATH, 'utf8');
    openpgp.initWorker({});
    const openpgpPublicKey = await openpgp.key.readArmored(publicKey);
    const openpgpPrivateKey = await openpgp.key.readArmored(signingPrivateKey);
    await openpgpPrivateKey.keys[0].decrypt(process.env.PGP_PRIVATE_KEY_PASSPHRASE);
    const file = fs.readFileSync(zippedFile);
    const options = {
        message: openpgp.message.fromBinary(new Uint8Array(file)),
        publicKeys: openpgpPublicKey.keys,
        privateKeys: [openpgpPrivateKey.keys[0]],
        armor: false,
    };
    const encryptionResponse = await openpgp.encrypt(options);
    const encryptedFile = encryptionResponse.message.packets.write();
    fs.writeFileSync('./FileName.zip.pgp', encryptedFile);

    When I run this code using a macbook, the code works fine, and decryption and verifying the signature works fine as well on a macbook, but there is an error when trying to decrypt it on a windows system using symantec PGP

    FileName.zip.pgp:decrypt (3090:operation failed, encrypted session key is bad)

    Could anyone help out with why this would be happening?

    Daniel Huigens
    @twiss
    Symantec PGP is quite old - could you try decrypting with GnuPG, for example, to verify if there's any issue with the message? The code looks fine to me.
    Kevin Moutet
    @sinderw
    Hi, I was trying to retrieve a signature's creation time, and realized that although it is possible to specify it at creation, it is neither possible to retrieve it nor to specify its expiration time. Should we work on that?
    Daniel Huigens
    @twiss
    Hey :wave: For signature creation time, even though there's no function for it, there's a public property exported here: https://github.com/openpgpjs/openpgpjs/blob/5299561aa35a34282c1a9cc979cf81d498ea933d/openpgp.d.ts#L405 which should be fine to use.
    Re. signature expiration - this is rarely used in OpenPGP, do you have a use case for this?
    We don't even consider signature expiration in some cases (e.g. #1138) - probably that should be fixed first (and #1137)
    Kevin Moutet
    @sinderw
    Oh right. This property is on SignaturePacket so maybe we should actually make Signature.packets public again?
    Well, we communicate signed data over insecure channels. To avoid request duplication we signed the date too.
    As this design is flawed we are moving toward a challenge/response design, but along the way we realized that the signature date/expiration might have been used for that purpose.
    I indeed saw the issues #1137 and #1138. Is any help needed on those?
    Daniel Huigens
    @twiss

    Oh right. This property is on SignaturePacket so maybe we should actually make Signature.packets public again?

    Yeah it's a good point, actually then I agree we could add a Signature.prototype.getCreationTime, rather than exporting packets - probably it's cleaner that way.

    along the way we realized that the signature date/expiration might have been used for that purpose.

    I see, yeah makes sense. Though when it's an essential part of the application, I think signing and checking it explicitly in the application is not a bad idea, to make it more explicit what's going on, rather than implicitly relying on the properties of OpenPGP.

    I indeed saw the issues #1137 and #1138. Is any help needed on those?

    Yes, if you feel like taking a stab at these, please feel free! Probably what's required to fix these is to:

    • Pass a date to SignaturePacket.prototype.sign and verify
    • Set signature.created in sign rather than in the constructor
    • In verify, add a check for this.isExpired
    • In createVerificationObject, that same check can then be removed
    Kevin Moutet
    @sinderw
    Sorry for the late answer, I will work on that!
    Daniel Huigens
    @twiss
    :+1: Thanks a lot! :blush:
    Sean Ishikawa
    @ski14hs
    Hello, does anyone have any experience with an error encrypting text with a public key? Error encrypting message: Could not find primary user
    I store the armored key and read it in and generate text to create a .csv file. I am attempting to encrypt when i get the error.
    Some sample code:
    let publicKeyStream = await readFileAsync(PUBLIC_CREDENTIALS_PATH, 'utf8');
                let publicKey = await openpgp.readKey( { armoredKey : publicKeyStream});
                let privateKeyStream = await readFileAsync(PRIVATE_CREDENTIALS_PATH, 'utf8');
                let privateKey = await openpgp.readKey( {armoredKey : privateKeyStream });
                console.log(csvContent);
                let textToEncrypt = openpgp.Message.fromText(csvContent);
                csvContent = await openpgp.encrypt({
                    message: textToEncrypt,
                    publicKeys: publicKey,
                    privateKeys: privateKey,
                });
    Daniel Huigens
    @twiss
    Hey :wave: This is probably an issue with the key (i.e. that it doesn't contain a User ID). If the public key is publicly available, you could post it here and I can check, if you want
    Sean Ishikawa
    @ski14hs

    Forgive my ignorance, but from what I can see it seems like a normal key, begins with:

    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: BCPG v1.64
    ....
    -----END PGP PUBLIC KEY BLOCK-----

    Is there supposed to be more than this? It was a file supplied by a client. Will I not be able to encrypt using this key and OpenPGP.js?

    Daniel Huigens
    @twiss
    It's a bit difficult to tell just from that. You could feed it to gpg --list-packets (or https://dump.sequoia-pgp.org/ if you're comfortable posting it there) and check if there's a User ID packet
    Sean Ishikawa
    @ski14hs
    It appears that there is
    User ID Packet, old CTB, 52 bytes
    Value: [filename_2033] [email@email].org
    ( changed filename and email but a value was there)
    Daniel Huigens
    @twiss
    Hmm. Could you try setting openpgp.config.tolerant = false before parsing the key, and see if you get a different (more informative) error? Maybe OpenPGP.js fails to parse the User ID packet for some reason
    Sean Ishikawa
    @ski14hs
    hopefully i did it correctly, but the error now says ReferenceError: TextDecoder is not defined
    Sean Ishikawa
    @ski14hs
    I do import util before any of this
    Sean Ishikawa
    @ski14hs
    Also! I am using node 8.9.3, perhaps that could cause the issue?
    Daniel Huigens
    @twiss
    Ah yeah, that makes more sense. Updating to Node.js 11+ should fix this issue, indeed
    Sean Ishikawa
    @ski14hs
    is there a page listing previous versions of openPGP and the relevant Node dependencies?
    Daniel Huigens
    @twiss
    OpenPGP.js v4 supports older versions (though I don't know the exact minimum version). However, Node.js 8 is end-of-life and no longer receives security patches, so using it is insecure
    Sean Ishikawa
    @ski14hs
    is there a page with the v4 documentation?
    Sean Ishikawa
    @ski14hs

    Sorry for more questions but i'm getting a different error trying to roll back to v4.10.10

    let PublicKeyStream = await readFileAsync(CREDENTIALS_PATH, 'utf8');
    let PublicKey = (await openpgp.key.readArmored( PublicKeyStream )).keys;
    let textToEncrypt = openpgp.message.fromText(csvContent);
                csvContent = await openpgp.encrypt({
                    message: textToEncrypt,
                    publicKeys: [PublicKey],
                });

    should work if my public key file is stored at CREDENTIALS_PATH correct?
    I am getting a key.getPrimaryUser is not a function error

    Sean Ishikawa
    @ski14hs
    I believe I correctly brought the key in as when i log the public key i get
    [ Key {
        keyPacket:
         PublicKey {
           tag: 6,
           version: 4,
           created: 2021-03-09T23:38:15.000Z,
           algorithm: 'dsa',
           params: [Array],
           expirationTimeV3: 0,
           fingerprint: [Object],
           keyid: [Object],
           packets: [Object],
           fromStream: false },
        revocationSignatures: [],
        directSignatures: [],
        users: [ [Object] ],
        subKeys: [ [Object] ] } ]
    Sean Ishikawa
    @ski14hs
    Found the error, readme was updated to show .keys isn't what is supposed to be passed, but .keys[0]
    Sean Ishikawa
    @ski14hs

    I have another issue regarding decrypting:
    I am getting Error during parsing. This message / key probably does not conform to a valid OpenPGP format.
    Based this time I am reading in a message to decrypt:

    let PrivateKeyStream = await readFileAsync(CREDENTIALS_PATH, 'utf8');
    let PrivateKey = (await openpgp.key.readArmored( PrivateKeyStream )).keys[0];
    const encryptedData = await readFileAsync(localPath, 'utf8')
    let encryptedUint8 = new TextEncoder().encode(encryptedData);
    let encryptedMessage = await openpgp.message.read( encryptedUint8 )
    const { data: decrypted } = await openpgp.decrypt({
                            message: encryptedMessage,
                            privateKeys : [PrivateKey],
    });
    console.log(decrypted);

    I am able to decrypt the file using Kleopatra