Skip to content
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

Add multiple Private Keys to Encryption keys #277

Open
civteam-amonplaisir opened this issue Jan 24, 2024 · 11 comments
Open

Add multiple Private Keys to Encryption keys #277

civteam-amonplaisir opened this issue Jan 24, 2024 · 11 comments

Comments

@civteam-amonplaisir
Copy link

I have a case where I have 2 .key files that are required to be within the private-keys-v1.d folder before the file can be decrypted. I currently have both private keys and when I try to decrypt the file (by adding 1 of the private keys as a public key in an array with he actual public key) I get the message "Could not find any signing keys in keyring
at PgpCore.Utilities.FindBestSigningKey(PgpSecretKeyRingBundle secretKeyRingBundle)" I searched all over to find a solution and wasn't able to find one. Please let me know if you can help. Here is a snippet:

publicKeys has (FileInfo(.key), FileInfo(.asc)
FileInfo privateKey = new FileInfo(fullSecondKeyFilePath);
EncryptionKeys encryptionKeys = new EncryptionKeys(publicKeys, privateKey, decryptionKey.PassPhrase);

        using (PGP pgp = new PGP(encryptionKeys))
        {

            FileInfo inputFile = new FileInfo(fileUploadedPath);
            FileInfo outputFile = new FileInfo(fileOutputPath);

            await pgp.DecryptFileAsync(inputFile, outputFile);


            Stream outputStream = outputFile.OpenRead();

            string decryptedFileContentType;

            new FileExtensionContentTypeProvider().TryGetContentType(encryptedFileName, out decryptedFileContentType);

            return File(outputStream, decryptedFileContentType);
        }
@mattosaurus
Copy link
Owner

Hi, if you're using multiple keys to encrypt then you need to provide 2 (or more) public keys and not a public key and a private key. You're seeing this error because

I try to decrypt the file (by adding 1 of the private keys as a public key in an array with he actual public key)

The expected way of using multiple keys is illustrated in the below test.

[Theory]
[InlineData(KeyType.Generated)]
[InlineData(KeyType.Known)]
[InlineData(KeyType.KnownGpg)]
public async Task DecryptAsync_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType)
{
// Arrange
TestFactory testFactory = new TestFactory();
TestFactory testFactory2 = new TestFactory();
await testFactory.ArrangeAsync(keyType, FileType.Known);
await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known);
List<FileInfo> keys = new List<FileInfo>()
{
testFactory.PublicKeyFileInfo,
testFactory2.PublicKeyFileInfo
};
EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKeyFileInfo, testFactory.Password);
EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyFileInfo, testFactory2.Password);
PGP pgpEncrypt = new PGP(encryptionKeys);
PGP pgpDecrypt = new PGP(decryptionKeys);
// Act
await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo);
await pgpEncrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo);
await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory2.DecryptedContentFileInfo);
// Assert
using (new AssertionScope())
{
testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue();
testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue();
testFactory2.DecryptedContentFileInfo.Exists.Should().BeTrue();
File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content);
File.ReadAllText(testFactory2.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content);
}
// Teardown
testFactory.Teardown();
testFactory2.Teardown();
}

@civteam-amonplaisir
Copy link
Author

civteam-amonplaisir commented Jan 25, 2024

The only thing is I don't have control over the encryption of the file. It is a third party doing the encryption. I have attempted to only pass in 1 of the private keys into the encryption keys constructor and I am still receiving the same error. I was wondering if I would be able to have 2 private keys passed in together (2 .key files)? And then have 1 public key (1 .asc file)?

@mattosaurus
Copy link
Owner

If they're using 2 public keys to encrypt the file then you should be able to decrypt it using either of the associated private keys (as demonstrated in the above test).

Is it possible that they're encrypting it with your public key and signing it with their private key? If so you'd need to use the DecryptAndVerify method with your private key and their public key.

Can you decrypt these files using a command line utility instead of PGPCore? If so it's possible PGPCore is missing some functionality or that you're using the wrong method.

@civteam-amonplaisir
Copy link
Author

I am able to decrypt using gpg4win command line utility. Once I added the 2 .key files to the private-keys-v1.d folder, I was able to decrypt with only the public .asc key. I will try DecryptAndVerify and follow up

@civteam-amonplaisir
Copy link
Author

I am still getting the same error after changing the method. I am getting this error when initializing the EncryptionKeys

@mattosaurus
Copy link
Owner

That's probably because you're adding one of the private keys as a public key.

If you can provide a self-contained solution that replicates the issue then I'll take a look in more detail.

@civteam-amonplaisir
Copy link
Author

Okay sure thing I will create a solution that replicates this

@civteam-amonplaisir
Copy link
Author

PgpDecryptionTest.zip
I needed to scrub the files as it has private data but I placed dummy references to them there

@civteam-amonplaisir
Copy link
Author

Let me see if I could encrypt a random file

@mattosaurus
Copy link
Owner

A few things I've spotted.

EncryptionKeys encryptionKeys = new EncryptionKeys(publicKeys[0], "Passphrase"); //Throws error here

This overload of EncryptionKeys is expecting a private key, not a public key as the first argument.

The DecryptAndVerifyAsync method requires both a public key and a private key to be provided in the EncryptionKeys object like so.

EncryptionKeys encryptionKeys = new EncryptionKeys(publicKeys, testFactory.PrivateKeyFileInfo, testFactory.Password);

@civteam-amonplaisir
Copy link
Author

Okay I removed the passphrase and added all of the keys into a list of FileInfo of .asc, .key, .key. I then went to decrypt the file as DecryptAsync and received an error message of this "null reference object reference not set to an instance of an object" This is the line it throws the error "at PgpCore.EncryptionKeys.FindSecretKey(Int64 keyId)". Thats when I put all of the keys as public keys

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants