Powershell: Send a mime encrypted email with excel file attachment
Hi guys!
I've a tricky challenge.
I try to send mime encrypted mails.
Therefore I search in AD by using "cn" to get the certificate and mail address.
so far so good....
The native email without attachment run fine. email was sent encrypted:
$RecipientCN = $null
$RootDSE = $null
$Certificate = $null
$UserCertificate = $null
$ExcelFile = "C:\Temp\123.xlsx"
$RecipientCN='<cn>'
$SearchForestForPerson = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://DC=domain,DC=com")
$SearchForestForPerson.SearchScope = "subtree"
$SearchForestForPerson.PropertiesToLoad.Add("mail") | Out-Null
$SearchForestForPerson.PropertiesToLoad.Add("usercertificate") | Out-Null
$SearchForestForPerson.Filter = ("(&(objectClass=person)(CN=$RecipientCN))")
$Recipient = $SearchForestForPerson.FindOne()
$ChosenCertificate = $null
$Now = Get-Date
If ($Recipient.Properties.usercertificate -ne $null) {
ForEach ($UserCertificate in $Recipient.Properties.usercertificate) {
$ValidForSecureEmail = $false
$Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$UserCertificate
$Extensions = $Certificate.Extensions
ForEach ($Extension in $Extensions) {
If ($Extension.EnhancedKeyUsages -ne $null) {
ForEach ($EnhancedKeyUsage in $Extension.EnhancedKeyUsages) {
If ($EnhancedKeyUsage.FriendlyName -ine "Secure Email") {
$ValidForSecureEmail = $true
break
}
}
If ($ValidForSecureEmail) {
break
}
}
}
If ($ValidForSecureEmail) {
If ($Now -gt $Certificate.NotBefore.AddMinutes(-5) -and $Now -lt $Certificate.NotAfter.AddMinutes(5)) {
$ChosenCertificate = $Certificate
}
}
If ($ChosenCertificate -ne $null) {
break
}
}
}
Add-Type -assemblyName "System.Security"
$MailClient = New-Object System.Net.Mail.SmtpClient "<smtp server>"
$Message = New-Object System.Net.Mail.MailMessage
$Message.To.Add($Recipient.properties.mail.item(0))
$Message.From = "<sender address>"
$Message.Subject = "Unencrypted subject of the message"
$Body = "This is the mail body"
$MIMEMessage = New-Object system.Text.StringBuilder
$MIMEMessage.AppendLine('Content-Type: text/plain; charset="UTF-8"') | Out-Null
$MIMEMessage.AppendLine('Content-Transfer-Encoding: 7bit') | Out-Null
$MIMEMessage.AppendLine() | Out-Null
$MIMEMessage.AppendLine($Body) | Out-Null
[Byte[]] $BodyBytes = [System.Text.Encoding]::ASCII.GetBytes($MIMEMessage.ToString())
$ContentInfo = New-Object System.Security.Cryptography.Pkcs.ContentInfo (,$BodyBytes)
$CMSRecipient = New-Object System.Security.Cryptography.Pkcs.CmsRecipient $ChosenCertificate
$EnvelopedCMS = New-Object System.Security.Cryptography.Pkcs.EnvelopedCms $ContentInfo
$EnvelopedCMS.Encrypt($CMSRecipient)
[Byte[]] $EncryptedBytes = $EnvelopedCMS.Encode()
$MemoryStream = New-Object System.IO.MemoryStream @(,$EncryptedBytes)
$AlternateView = New-Object System.Net.Mail.AlternateView($MemoryStream, "application/pkcs7-mime; smime-type=enveloped-data;name=smime.p7m")
$Message.AlternateViews.Add($AlternateView)
$MailClient.Send($Message)
...but I've no success with an encrypted email with attached excel file ($ExcelFile).
Do anyone have an idea or better a script code which I can use to send an encrypted email with an attachment?
Thanks!
Thomminger
I've a tricky challenge.
I try to send mime encrypted mails.
Therefore I search in AD by using "cn" to get the certificate and mail address.
so far so good....
The native email without attachment run fine. email was sent encrypted:
$RecipientCN = $null
$RootDSE = $null
$Certificate = $null
$UserCertificate = $null
$ExcelFile = "C:\Temp\123.xlsx"
$RecipientCN='<cn>'
$SearchForestForPerson = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://DC=domain,DC=com")
$SearchForestForPerson.SearchScope = "subtree"
$SearchForestForPerson.PropertiesToLoad.Add("mail") | Out-Null
$SearchForestForPerson.PropertiesToLoad.Add("usercertificate") | Out-Null
$SearchForestForPerson.Filter = ("(&(objectClass=person)(CN=$RecipientCN))")
$Recipient = $SearchForestForPerson.FindOne()
$ChosenCertificate = $null
$Now = Get-Date
If ($Recipient.Properties.usercertificate -ne $null) {
ForEach ($UserCertificate in $Recipient.Properties.usercertificate) {
$ValidForSecureEmail = $false
$Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$UserCertificate
$Extensions = $Certificate.Extensions
ForEach ($Extension in $Extensions) {
If ($Extension.EnhancedKeyUsages -ne $null) {
ForEach ($EnhancedKeyUsage in $Extension.EnhancedKeyUsages) {
If ($EnhancedKeyUsage.FriendlyName -ine "Secure Email") {
$ValidForSecureEmail = $true
break
}
}
If ($ValidForSecureEmail) {
break
}
}
}
If ($ValidForSecureEmail) {
If ($Now -gt $Certificate.NotBefore.AddMinutes(-5) -and $Now -lt $Certificate.NotAfter.AddMinutes(5)) {
$ChosenCertificate = $Certificate
}
}
If ($ChosenCertificate -ne $null) {
break
}
}
}
Add-Type -assemblyName "System.Security"
$MailClient = New-Object System.Net.Mail.SmtpClient "<smtp server>"
$Message = New-Object System.Net.Mail.MailMessage
$Message.To.Add($Recipient.properties.mail.item(0))
$Message.From = "<sender address>"
$Message.Subject = "Unencrypted subject of the message"
$Body = "This is the mail body"
$MIMEMessage = New-Object system.Text.StringBuilder
$MIMEMessage.AppendLine('Content-Type: text/plain; charset="UTF-8"') | Out-Null
$MIMEMessage.AppendLine('Content-Transfer-Encoding: 7bit') | Out-Null
$MIMEMessage.AppendLine() | Out-Null
$MIMEMessage.AppendLine($Body) | Out-Null
[Byte[]] $BodyBytes = [System.Text.Encoding]::ASCII.GetBytes($MIMEMessage.ToString())
$ContentInfo = New-Object System.Security.Cryptography.Pkcs.ContentInfo (,$BodyBytes)
$CMSRecipient = New-Object System.Security.Cryptography.Pkcs.CmsRecipient $ChosenCertificate
$EnvelopedCMS = New-Object System.Security.Cryptography.Pkcs.EnvelopedCms $ContentInfo
$EnvelopedCMS.Encrypt($CMSRecipient)
[Byte[]] $EncryptedBytes = $EnvelopedCMS.Encode()
$MemoryStream = New-Object System.IO.MemoryStream @(,$EncryptedBytes)
$AlternateView = New-Object System.Net.Mail.AlternateView($MemoryStream, "application/pkcs7-mime; smime-type=enveloped-data;name=smime.p7m")
$Message.AlternateViews.Add($AlternateView)
$MailClient.Send($Message)
...but I've no success with an encrypted email with attached excel file ($ExcelFile).
Do anyone have an idea or better a script code which I can use to send an encrypted email with an attachment?
Thanks!
Thomminger
Please also mark the comments that contributed to the solution of the article
Content-ID: 240989
Url: https://administrator.de/contentid/240989
Printed on: December 3, 2024 at 07:12 o'clock
3 Comments
Latest comment
Hello Thomminger, welcome to administrator.de!
As far as i know, encrypted MIME attachments are not supported with System.Net.Mail. You may consider to implement your
own security mecanism (embed your mail as an encrypted attachment, ... like a scrambled *.zip file for example). Or use a third party programming-library for composing your messages.
A solution could be this library: http://www.codeproject.com/Articles/41727/An-S-MIME-Library-for-Sending ... which also supports attachments. You can compile this code an use the corresponding *.dll in your powershell-project by loading it via add-type.
Here is an example with this library and Powershell:
This sends an encrypted and signed message with an included attachment:
For simplicity i have compiled the library for you, download it here: Cpi.Net.SecureMail.dll (Compiled against .NET Framework 3.5)
Regards
@colinardo
As far as i know, encrypted MIME attachments are not supported with System.Net.Mail. You may consider to implement your
own security mecanism (embed your mail as an encrypted attachment, ... like a scrambled *.zip file for example). Or use a third party programming-library for composing your messages.
A solution could be this library: http://www.codeproject.com/Articles/41727/An-S-MIME-Library-for-Sending ... which also supports attachments. You can compile this code an use the corresponding *.dll in your powershell-project by loading it via add-type.
Here is an example with this library and Powershell:
This sends an encrypted and signed message with an included attachment:
# load managed code library
add-type -Path "D:\Cpi.Net.SecureMail.dll"
# load cryptocertificate by defining path and password
$mycert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("D:\yourcryptocert.p12","PASSWORD_OF_CERTIFICATE")
# load recipient public certificate
$recipientCert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("D:\recipient.cer")
# create secure mail message
$mail = new-object Cpi.Net.SecureMail.SecureMailMessage
# add sender and recipient
$mail.From = new-object Cpi.Net.SecureMail.SecureMailAddress("sender@domain.com","SENDERNAME",$mycert,$mycert)
$mail.To.Add((new-object Cpi.Net.SecureMail.SecureMailAddress("recipient@domain.com","RECIPIENTNAME",$recipientCert)))
$mail.Body = "This is a secure message with Attachment"
# add secure attachment to mail message
$mail.Attachments.Add((new-object Cpi.Net.SecureMail.SecureAttachment("d:\yourattachment.txt")))
# set mail properties (encrypted and signed)
$mail.IsSigned = $true
$mail.IsEncrypted = $true
# create smtp-client to send mail message
$smtp = new-object System.Net.Mail.SmtpClient("smtp.yourdomain.com", 25)
$smtp.Credentials = new-object System.Net.NetworkCredential("SMTPUSERNAME","SMTPPASSWORD")
# finally send mail
$smtp.Send($mail)
Regards
@colinardo