I want to encrypt the mail using S/MIME standard using powershell. I am able to send mail with attachment(without the encryption from powershell). But when i tried to encrypt it with the following code. It doesn't work as it just remove the file and send the body unencrypted. I am using powershell version 5. For testing purposes I want to use previously generated certificates rather than fetching from somewhere. Please advise on my problem or if there is any better approach.
$email = "*********@gmail.com"
$pass = "*******"
$smtpServer = "smtp.gmail.com"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.EnableSsl = $true
$msg.From = "$email"
$msg.To.Add("*****b@***.com")
$msg.BodyEncoding = [system.Text.Encoding]::Unicode
$msg.SubjectEncoding = [system.Text.Encoding]::Unicode
$msg.Headers.Add('MIME-Version','asd')
$msg.Headers.Add("From","**abc**")
$msg.Headers.Add("To","**xyz**")
$msg.Headers.Add("Date","11-11-1111")
$msg.Headers.Add("Subject","asfasdd")
$msg.HeadersEncoding =[system.Text.Encoding]::UTF8
$msg.IsBodyHTML = $true
$msg.Subject = "Test mail from PS"
$msg.Body = "<h2> Test mail from PS </h2>
</br>
Hi there
"
$file= get-item -Path "E:\siddhant\abc.txt"
$SMTP.Credentials = New-Object System.Net.NetworkCredential("$email", "$pass");
$Certname="helloo"
$Cert = New-SelfSignedCertificate -certstorelocation E:\siddhant -dnsname $Certname
$pw = ConvertTo-SecureString -String "Pazzword" -Force -AsPlainText
$thumbprint = $Cert.Thumbprint
$MIMEMessage = New-Object system.Text.StringBuilder
$MIMEMessage.AppendLine("MIME-Version: 1.0") | Out-Null
$MIMEMessage.AppendLine("Content-Type: multipart/mixed; boundary=unique-boundary-1") | Out-Null
$MIMEMessage.AppendLine() | Out-Null
$MIMEMessage.AppendLine("This is a multi-part message in MIME format.") | Out-Null
$MIMEMessage.AppendLine("--unique-boundary-1") | Out-Null
$MIMEMessage.AppendLine("Content-Type: text/plain") | Out-Null
$MIMEMessage.AppendLine("Content-Transfer-Encoding: 7Bit") | Out-Null
$MIMEMessage.AppendLine()
$MIMEMessage.AppendLine($Body) | Out-Null
$MIMEMessage.AppendLine() | Out-Null
$MIMEMessage.AppendLine("--unique-boundary-1") | Out-Null
$MIMEMessage.AppendLine("Content-Type: application/octet-stream; name="+ $file.Name) | Out-Null
$MIMEMessage.AppendLine("Content-Transfer-Encoding: base64") | Out-Null
$MIMEMessage.AppendLine("Content-Disposition: attachment; filename="+ $file.Name) | Out-Null
$MIMEMessage.AppendLine() | Out-Null
[Byte[]] $binaryData = [System.IO.File]::ReadAllBytes($file)
[string] $base64Value = [System.Convert]::ToBase64String($binaryData, 0, $binaryData.Length)
[int] $position = 0
while($position -lt $base64Value.Length)
{
[int] $chunkSize = 100
if (($base64Value.Length - ($position + $chunkSize)) -lt 0)
{
$chunkSize = $base64Value.Length - $position
}
$MIMEMessage.AppendLine($base64Value.Substring($position, $chunkSize))
$MIMEMessage.AppendLine()
$position += $chunkSize;
}
$MIMEMessage.AppendLine("--unique-boundary-1--") | Out-Null
[Byte[]] $BodyBytes = [System.Text.Encoding]::ASCII.GetBytes($MIMEMessage.ToString())
$ContentInfo = New-Object -TypeName System.Security.Cryptography.Pkcs.ContentInfo -
ArgumentList(,$BodyBytes)
$CMSRecipient = New-Object System.Security.Cryptography.Pkcs.CmsRecipient $Cert
$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")
$msg.AlternateViews.Add($AlternateView)
$smtp.Send($msg)