1

I'm getting this error when trying to decrypt a MIME message:enter image description here

When I decrypt it in my local machine I can decrypt the mail without any problem, but the app deployed in server can't decrypt and results in this error. this is the code I'm using for decrypting

GraphServiceClient graphClient = new GraphServiceClient(clientSecretCredential, new string[] { _laCaixaSettings.GraphApiSettings.Scope });
var streamMessage = await graphClient.GetMessage(_laCaixaSettings.GraphApiSettings.UserId, pasarelaSettings.FicheroId);
using var message = await MimeMessage.LoadAsync(streamMessage);
var decryptedStream = await MimeMailUtils.Decrypt(message, _laCaixaSettings.GraphApiSettings.PrivateCertificate);
    
public static async Task<Stream> GetMessage(this GraphServiceClient graphServiceClient, string userId, string messageId)
{
    var request = graphServiceClient.Users[userId].Messages[messageId].Request().GetHttpRequestMessage();
    request.RequestUri = new Uri(request.RequestUri.OriginalString + "/$value");
    var response = await graphServiceClient.HttpProvider.SendAsync(request);
    response.EnsureSuccessStatusCode();
    var content = await response.Content.ReadAsStreamAsync();
    content.Position = 0;
    return content;
}

public static async Task<MimeEntity> Decrypt(MimeMessage message, X509Certificate2 certificate)
{
    var encryptedContent = (ApplicationPkcs7Mime)message.Body;
    using var context = new WindowsSecureMimeContext(StoreLocation.CurrentUser);
    context.Import(StoreName.CertificateAuthority, certificate);
    return await encryptedContent.DecryptAsync(context);
}

And this is how I get the certificate

public void SetSecrets()
{
    using KeyVaultClient client = VaultClientExtensions.GetKeyVaultClient(AzureVaultManagerSettings.ClientId, AzureVaultManagerSettings.ClientSecret);
    var secret = AsyncUtil.RunSync(() => client.GetSecret<string>(AzureVaultManagerSettings.SecretUrl));
    GraphApiSettings.PrivateCertificate = new X509Certificate2(
        Convert.FromBase64String(secret),
        string.Empty,
        X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
}

I believe the problem could be that this certificate is not installed in the server. Could anyone help me with this? Thanks in advance!

1 Answers1

1

You don't have access to StoreName.CertificateAuthority.

If you look at the stack trace in the exception, it is failing in System.Security.Cryptography.X509Certificates.X509Store.Open()

Generally, the StoreName.CertificateAuthority is only accessible to admin users.

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • Hi! Thanks for your fast answer. So the problem would be in the moment I try to import the certificate, am I right? If not, how could I solve this? Should I give admin perms to the app? – victor garcia exposito Feb 28 '22 at 07:21
  • I saw that using the parameter of ephemeralKeySet when importing the certificate it should be enough as the app shouldn't write anything on the machine. Anyway as I read in your documentation the WindowsSecureMimeContext gets initialized in the user's store location, but should I specify that in the constructor of the class? – victor garcia exposito Feb 28 '22 at 07:54
  • Hi Jeffrey, Could you have an eye on this? Why the decryption is trying to open the certificates store when I have the certificate in memory? – victor garcia exposito Mar 01 '22 at 09:37
  • Because you are importing it to the store. – jstedfast Mar 01 '22 at 11:51
  • Thanks a lot again for your answer! I tried also importing it to the user's store (StoreName.My) and it din't work either. As this is an app service I can't give any user admin privileges to do this. Is there any other strategy I could follow to decrypt the message with Mimekit? – victor garcia exposito Mar 01 '22 at 12:03
  • 1
    Use a TemporarySecureMimeContext – jstedfast Mar 01 '22 at 12:23
  • The problem with that is when I try to generate the x509Certificate with the method X509Certificate2Extensions.AsBouncyCastleCertificate() I get the error "A suitable private key could not be found for decrypting." as I mentioned [here](https://stackoverflow.com/questions/71063045/mimekit-unable-to-cast-object-of-type-org-bouncycastle-asn1-derapplicationspe) I'm going to post another thread as now I'm encountering this new problem. Anyway thanks a lot for your patience and efforts. – victor garcia exposito Mar 01 '22 at 12:41