 |
|
 |
I have noticed that the SecureMailMessage currently supports only the "Body" property and does not support AlternateView's and LinkedResource's. Are there plans to support them?
Ken Layton
|
|
|
|
 |
|
 |
Hello
I try to use the System.Net.Mail.MailMessage and it me does not appear in the system references, then I cannot use the SecureMailMessage .I have Net Framework 2.0. What does it fail me to do?
Thanks for your help.
|
|
|
|
 |
|
 |
Hi Pete,
Great work with this!
Question: Can this library be used to decrypt and read emails that have been sent to me?
Edwin
|
|
|
|
 |
|
 |
Sorry, but no. Making code that writes to a spec like S/MIME is pretty easy, because you only have to make sure that what you output is valid. Making code that READS a spec like S/MIME is quite a lot harder, because you have to account for every possible thing that's technically valid (as well other stuff, probably, that's technically not valid, but the big name mail clients do it anyway). Frankly, that sounds like a lot of work, and I'm REALLY lazy.
But if the crypto stuff is your primary concern here, the heavy lifting is all done by the SignedCms class (for signed messages) and the EnvelopedCms class (for encrypted messages). They're both in System.Security.dll, in the System.Security.Cryptography.Pkcs namespace, and they're reasonably well-documented in MSDN. So if your goal is to pull apart signed/encrypted messages in sort of an ad hoc way, you should be able to piece something together without too much drama.
Best of luck,
-Pete
|
|
|
|
 |
|
 |
I downloaded the S/Mime library and am using it to encrypt messages and it works beautifully.
However, when I try to attach a file to the message it never gets sent. No errors are thrown. I looked at the code library and it appears everything is in order but I must be leaving something out.
I'm using a file that is in a database and am passing the byte array, filename, and media type to the following code.
I get the email message minus the attachment.
This might be a situation where I can't see the forest for the trees but any help would be appreciated.
Public Sub SendEncryptedEmails(ByRef Certificate As Byte(), ByVal Attachment As Byte(), ByVal AttachmentName As String, ByVal AttachmentType As String)
Dim SecureMessage As New SecureMailMessage()
Dim MyAttachment As New SecureAttachment(Attachment, AttachmentName, AttachmentType)
Dim recipientCert As X509Certificates.X509Certificate2 = New X509Certificates.X509Certificate2(Certificate)
SecureMessage.From = New SecureMailAddress("elmerfudd@test.com", "Looney Support", recipientCert)
SecureMessage.To.Add(New SecureMailAddress("bugs@test.com", "Tunes", recipientCert))
SecureMessage.Attachments.Add(MyAttachment)
SecureMessage.Subject = "Test Encryption Message"
SecureMessage.Body = "<h1>This is a test for attachments</h1>"
SecureMessage.IsBodyHtml = True
SecureMessage.IsSigned = False
SecureMessage.IsEncrypted = True
Dim smpt As SmtpClient = New SmtpClient("myServersIP", 25)
smpt.Send(SecureMessage)
|
|
|
|
 |
|
 |
It looks like if I disable encryption then the attachment comes through.
Not really sure why this is but I'm doing some more digging.
|
|
|
|
 |
|
 |
Well, everything certainly works for me, at least in the following specific instance.
SecureAttachment attachment = new SecureAttachment(Encoding.ASCII.GetBytes("San Dimas High School Football RULES!"), "Pete.txt", "text/plain");
X509Certificate2 aliceCert = CryptoHelper.FindCertificate("abcde");
X509Certificate2 bobCert = CryptoHelper.FindCertificate("12345");
SecureMailMessage message = new SecureMailMessage();
message.From = new SecureMailAddress("alice@cynicalpirate.com", "Alice", aliceCert);
message.To.Add(new SecureMailAddress("bob@cynicalpirate.com", "Bob", bobCert));
message.Attachments.Add(attachment);
message.Subject = "Test Encryption Method";
message.Body = "<h1>This is is a test for attachments</h1>";
message.IsBodyHtml = true;
message.IsSigned = false;
message.IsEncrypted = true;
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("localhost", 25);
client.Send(message);
The mail is successfully encrypted, and the attachment is there when I open it. Try this code and see if it works for you. What parameters are you sending to the method you posted? (File name, content type, etc.) If I can reproduce the problem you're having, I can have a look at what's going on.
|
|
|
|
 |
|
 |
Thanks so much for your reply.
The parameters are as follows:
The Certificate, The Attachment itself, The name of the attached file and the type.
It all works if I don't encryption the message.
I can see everything as I should.
Otherwise with encryption I get the message but no attachment. That's what is so puzzling.
I'll try your test code as well. The only thing I see is that you are encoding your string attachment, I guess mine is binary.
Public Sub SendEncryptedEmails(ByRef Certificate As Byte(), ByVal Attachment As Byte(), ByVal AttachmentName As String, ByVal AttachmentType As String)
Dim SecureMessage As New SecureMailMessage()
Dim MyAttachment As New SecureAttachment(Attachment, AttachmentName, AttachmentType)
Dim recipientCert As X509Certificates.X509Certificate2 = New X509Certificates.X509Certificate2(Certificate)
SecureMessage.From = New SecureMailAddress("elmerfudd@test.com", "Looney Support", recipientCert)
SecureMessage.To.Add(New SecureMailAddress("bugs@test.com", "Tunes", recipientCert))
SecureMessage.Attachments.Add(MyAttachment)
SecureMessage.Subject = "Test Encryption Message"
SecureMessage.Body = "<h1>This is a test for attachments</h1>"
SecureMessage.IsBodyHtml = True
SecureMessage.IsSigned = False
SecureMessage.IsEncrypted = True
Dim smpt As SmtpClient = New SmtpClient("myServersIP", 25)
smpt.Send(SecureMessage)
|
|
|
|
 |
|
 |
I tried using your code which is very close to mine and I just hard coded a test string and encoded it just like you with the same results.
No attachment.
Not really sure where to go from here.
Thank you for your efforts.
|
|
|
|
 |
|
 |
Pete,
I'm going to rebuild the secure mail DLL and copy it into my project and see if that might fix it.
Is the secure mail DLL the only file I need to copy and make a reference?
I noticed there was another file a secure mail pdb file. Does the DLL need that one?
Roy
|
|
|
|
 |
|
 |
Pete,
Do you have any ideas as to why the attachments aren't being sent in the encrypted emails?
I'm getting ready to look at another library but before I do I want to exhaust my efforts with this.
Thank You.
|
|
|
|
 |
|
 |
I really don't know what to tell you, dude. I can't reproduce the results that you're seeing. Everything works fine for me, and for just about everybody else who's using the library, so it seems like there's something specific to your environment. Which mail client are you using to read the encrypted message?
|
|
|
|
 |
|
 |
I'm using MS Office Outlook 2007.
I thought maybe it had something to do with VS and Windows 7 but I deployed my project to a server with the same results.
This is very strange indeed since the attachments show up if no encryption is used.
Is the downloadable library the latest? I downloaded this back in December. Just shooting darts at this point.
Thanks again.
|
|
|
|
 |
|
 |
hello,
i'm trying to use this code to send a simple signed message.
and it's shows that the digital signature is invalid because :The message contents may have been altered
what i'm doing wrong?
my code is:
SecureMailMessage message = new SecureMailMessage();
X509Certificate2 signingCert = new X509Certificate2(@"D:/XXX.pfx");
message.From = new SecureMailAddress("sender@XXX.XX.XX", "sender@XXX.XX.XX", signingCert, signingCert);
message.To.Add(new SecureMailAddress("myemail@XXX.XX.XX", "myemail@XXX.XX.XX", signingCert));
message.Subject = "This is a signed message";
message.Body = message.Body = "Sent from the Cpi.Net.SecureMail library!";
message.IsBodyHtml = true;
message.IsSigned = true;
message.IsEncrypted = false;
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("MySmtpUserName", 25);
client.UseDefaultCredentials = true;
client.Send(message);
|
|
|
|
 |
|
 |
The code looks okay to me, and similar code runs just fine from where I'm sitting. What SMTP server are you using? Is it altering rewriting the message that you're sending in transit?
|
|
|
|
 |
|
 |
Hello.
I'm currently using this API to send encrypted emails.
I've found a problem (or maybe I use it wrong).
When I try to send an encrypted email with images into the body (like could be a signature) the image doesn't appear at the reception. I think'its link ressourceis lost.
Can you help me with that?
Thank you.
Jean
|
|
|
|
 |
|
 |
I don't know what you're talking about. How are you putting images in the body? What's a link resource? Include a little sample code, and I'll have a look.
|
|
|
|
 |
|
 |
Hello.
Ok, I'll explain that better.
I'm using System.Net.Mail to send mails.
I've tried to use your library to encrypt them.
When you send a mail with images into the body (like a signature)
you have to add a LinkedResource to the MailMessage that has an identifier (cid:... in the html body message), then, you change into your html body the path to the image by (cid:...). When the receiver receives the mail, he can open it and see the signature.
Well, when I do that and use your library to encrypt it, it doesn't work.
I can't see the signature anymore.
You know what I mean?
See this example :
Look at the body of a mail message in an html format:
"<html>
<body>
<img src="cid:45804415-8fd4-4ad5-bffe-0656f2affe4e" width=394 height=499>
Hello
</body>
</html>"
This is the html text I send with an email containing a signature (cid:45804415-8fd4-4ad5-bffe-0656f2affee)
The tag "cid..." is the identifier of an image contained in the LinkedResources of the MailMessage:
For each signature we make a LinkedResource object like this :
LinkedResource resourceLinked = new LinkedResource(stream, "image/" + fileName);
resourceLinked.ContentId = "45804415-8fd4-4ad5-bffe-0656f2affee";
resourceLinked.TransferEncoding = TransferEncoding.Base64;
resources.Add(resourceLinked);
And, we put it into the LinkedResources of the mail in the AlternateViews:
AlternateView view = AlternateView.CreateAlternateViewFromString(body, this._mail.BodyEncoding, "text/html");
foreach (LinkedResource ressourceInner in resources)
{
view.LinkedResources.Add(ressourceInner);
}
this._mail.AlternateViews.Add(view);
Once this is done, we send the mail, and when we receive it, we can see the signatures into it as images.
Well, when I use your objects instead of mine (SecureMailMessage instead of MailMessage, SecureMailAddress instead of MailAddress...), we lost the LinkedResources, and the signatures images are not viewable at the reception.
I don't know if it's really clear.
Can you help me with that?
Thank you.
|
|
|
|
 |
|
 |
Well, I guess here's the part I'm unclear on. This library doesn't even prentend to support what you're trying to do. It doesn't handle alternate views at all. There's not even an AlternateViews property on SecureMailMessage. So I don't understand how you're porting your code to my library at all.
The short answer is, this library doesn't support alternate views or linked resources at all, and I'm not planning on supporting them in the future. Every time somebody sends me an e-mail message with a cute background image that makes the message look like a spiral-bound notebook, my thoughts turn to violence. And I'm not interested in implicitly encouraging that sort of behavior.
Of course, the license for the code is about as free-and-easy as you can get, so feel free to hack up the source to make it do whatever suits you. Just keep in mind that you're on your own.
|
|
|
|
 |
|
 |
You mention that SecureMailAddress might have two certificates for different purpose.
Like this
message.From = new SecureMailAddress
("alice@cynicalpirate.com", "Alice", encryptionCert, signingCert);
But I think we will never use encryptionCert because when we encryption the mail, we will use the public key of the recipient but not ours.
We only use encryptionCert when we receive the mail that other people send us an encryption mail.
My question is if we do use the encryptionCert when we send a mail.
|
|
|
|
 |
|
 |
Well, remember that when you send an encrypted e-mail in a mail client like Outlook, a copy of it gets stored in your Sent Items folder, which you can open and read if you want. That's because when Outlook encrypts the message, it uses the sender's public key, as well as all of the recipeients' keys. If it didn't, you'd just be left with an encrypted blob afterwards that you had no way of opening yourself. For this reason, it's good form to encrypt the message with the sender's key when sending encrypted e-mail, and so that's what this library does.
In short, the answer is yes...you do use the sender's encryption cert when sending encrypted e-mail, in just the same way as you use the recipients' certs.
Hope this helps,
-Pete
|
|
|
|
 |
|
 |
I got this running in development to send an encrypted email with no problem running in full trust. As soon as I switched to medium trust in the web.config (to simulate my web service provider), I get a security exception on the SmtpClient.Send method. The security exception is:
Request for the permission of type 'System.Security.Permissions.KeyContainerPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
Is there any way to get this to work in Medium trust to send an encrypted email?
|
|
|
|
 |
|
 |
Short answer, no. No self-respecting web host will let you have the kind of permissions you'd need to get this to work. In addition to the permissions you already stumbled on, you'll also need unrestricted web permission, which is a big deal, and UnmanagedCode permission, which is one of the most powerful CAS permissions that exists, and would effectively allow you to bypass CAS entirely on the server.
This doesn't have anything to do with my code; it's demanded by the underlying libraries that are doing the actual cryptographic work. So there's nothing that you or I can do about it. If you need to encrypt mail, you should probably end up doing what I do, which is rent an actual server (physical or virtual) and do your own IIS configuration. Or, if you can manage to talk your existing provider into giving you all the CAS permissions you'll need, let me know, and we'll brainstorm ways for you to completely take over the server. (That last bit was just a joke. I'm one of the good guys lately.)
|
|
|
|
 |
|
 |
I realize this doesn't have to do with your code, I was just wondering if there was a workaround to get it to work in Medium Trust. You mentioned that it's demanded by the underlying libraries that are doing the actual cryptographic work. I don't think it's the Encryption algorithms that won't run in Medium Trust, as I am able to use both RSA Encryption and Rijndae Encryption (managed code) to create an encrypted envelope with no problem in Medium trust. It's only when I try to send an encrypted email using the smtpclient.send method that the error occurs. Note that this is after your class has already created the encrypted email. Thus, the encryption has already been completed. Something in the smtpclient doesn't like the s/mime envelope.
Doesn't Microsoft think users in a shared hosting environment should be able to send encrypted emails? This should be a fairly common need.
|
|
|
|
 |
|
 |
Well, dude, that's simply not true. The actual interesting stuff in my library doesn't happen until the SecureMailMessage object is turned into a regular ol' MailMessage object. That happens either explicitly, when you call message.ToMailMessage(), or implictly, when you use it in a situation that expects a MailMessage instance. (It's done with an implicit casting operator.) Do this test to verify. Instead of sending your message (you don't have to instantiate an SmtpClient at all), just call ToMailMessage() on your encrypted message in medium trust. You'll get exactly the same failure that you're currently seeing, without even trying to send the message.
Also, it's unreasonable to make direct comparisons between the RSA and Rijndael algorithms (which are defined in mscorlib), and the signed and enveloped cms classes (which are defined in the System.Security dll). The first two algorithms are general-purpose, and a lot of work went into making them partial-trust-friendly. The stuff in System.Security.dll is a whole different story, and was simply not designed to run under medium trust.
It's certainly inconvenient, and I'm just as sad about it as you are, but learning how to deal with adversity is a big part of growing up. After all, I believe it was Shakespeare who said, "You take the good, you take the bad, you take 'em both and there you have The Facts of Life." Yeah...I'm pretty sure it was Shakespeare.
|
|
|
|
 |