Closed tharwania closed 3 years ago
Yes, both a private key and password are required for decryption.
I have tested on BouncyCastle. Empty password works there, not a null but an empty string. It's quite confusing when you can generate keys and encrypt without a password but for decryption password is required.
If you're using an empty string is it actually setting this as the password rather than there being no password set? If so then this is probably getting caught by a IsNullOrWhitespace check somehere in PgpCore which I could probably modify to just check if the password is null.
If the key actually does have no password then there's no functionality at present to deal with this scenario as I assumed there would always be a password required as this is best practise. If you'd like to add this functionality in then feel free to submit a PR.
@mattosaurus I found the issue, While constructing the EncryptionKeys Object, the password is only param separating private key and public key constructor, i.e
EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo);
EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo)
these two objects will always initialize a private key because a constructor without a password will always identify as a public key.
public async Task GenerateKeys_Encrypt_Decrypt_Without_Key_Password()
{
// Arrange
TestFactory testFactory = new TestFactory();
await testFactory.ArrangeAsync(KeyType.Known, FileType.Known);
PGP pgp = new PGP();
// Act
await pgp.GenerateKeyAsync(testFactory.PublicKeyFilePath, testFactory.PrivateKeyFilePath);
EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo);
EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo);
PGP pgpEncrypt = new PGP(encryptionKeys);
PGP pgpDecrypt = new PGP(decryptionKeys);
await pgpEncrypt.EncryptFileAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo);
await pgpDecrypt.DecryptFileAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo);
// Assert
Assert.True(testFactory.EncryptedContentFileInfo.Exists);
Assert.True(testFactory.DecryptedContentFileInfo.Exists);
Assert.Equal(testFactory.Content, testFactory.DecryptedContent.Trim());
// Cleanup
testFactory.Teardown();
}
I have written a failing test for more clarity. We need an enum or some identifier of what kind of key it is, but that will be a breaking change. What would you suggest in the scenario?
Hi, sorry for the delay in getting back to you on this. A private key without a password can be represented by using an empty string.
EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, "");
Whether using an empty string for this is a good idea or not is another matter but this should work for your issue.
GenerateKeys without a password, and Encrypt without a password but on DecryptFileAsync, it won't work without a password.