colinardo
Goto Top

Powershell: S-MIME verschlüsselte und signierte E-Mail inkl. sicherem Anhang verschicken (Mailkit-Bibliothek)

- edit (18.12.2020) -

back-to-topHinweis: Powershell Code mit der öffentlich frei verfügbaren Mailkit-Bibliothek statt der CPI.Net DLL findet ihr weiter unten im Beitrag als Download.



Falls Ihr vor dieser Aufgabe stehen solltet, gibt es hier eine Lösung dafür:
Der Code benötigt eine DLL die aus einem Projekt bei codeproject.com entstanden ist (Der c# Quellcode ist dort einsehbar). Falls Ihr keine Möglichkeit zum Kompilieren des Codes habt, könnt Ihr diese hier herunterladen (Hinweis: benötigt .NET 3.5).
back-to-topPowershell: Verschlüsselte und signierte E-Mail inkl. sicherem Anhang erstellen
Hinweise was anzupassen ist, findet Ihr im Quellcode
# Code-Bibliothek laden
add-type -Path ".\Cpi.Net.SecureMail.dll"  

# Zertifikat zur Verschlüsselung und Signierung der Mail inkl. dessen Passwort angeben
$mycert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("D:\yourcryptocert.p12","PASSWORD_OF_CERTIFICATE")  

# Öffentliches Zertifikat das Empfängers laden
$recipientCert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("D:\recipient.cer")  

# Sichere Mail-Nachricht erstellen
$mail = new-object Cpi.Net.SecureMail.SecureMailMessage

# Sender und Empfänger zur Nachricht hinzufügen
$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.Subject = "Dies ist der Betreff der Nachricht"  
$mail.Body = "Diese der Body der Nachricht"  

# Attachment zur Nachricht hinzufügen
$mail.Attachments.Add((new-object Cpi.Net.SecureMail.SecureAttachment("d:\yourattachment.txt")))  

# Maileigenschaften festlegen (verschlüsselt und signiert)
$mail.IsSigned = $true
$mail.IsEncrypted = $true

# SMTP-Client mit Credentials erstellen
$smtp = new-object System.Net.Mail.SmtpClient("smtp.yourdomain.com", 25)  
$smtp.Credentials = new-object System.Net.NetworkCredential("SMTPUSERNAME","SMTPPASSWORD")  

# senden der Nachricht
$smtp.Send($mail)


## edit (18.12.2020): ##

Da hier das Interesse ja doch einigermaßen hoch an dem Thema ist , habe ich mal eine Powershell-Funktion mit der frei verfügbaren Mailkit-Bibliothek gescriptet die so gut wie sämtliche Möglichkeiten von Send-MailMessage bietet und darüber hinaus zusätzliche wie Inline-Images im HTML-Code und natürlich das signierte, verschlüsselte und kombinierte signierte+verschlüsselte Mails unterstützt.

back-to-topDownload gibt's hier:


back-to-topmailkit_send_signed_encrypted_241025.zip

(siehe Kommentar weiter unten)


Viel Erfolg
Grüße @colinardo

Content-Key: 241025

Url: https://administrator.de/contentid/241025

Printed on: April 18, 2024 at 12:04 o'clock

Member: AnkhMorpork
AnkhMorpork Jun 16, 2014 at 17:18:54 (UTC)
Goto Top
Hallo,

feine Sache das!

Aber bei einigen wird es auf dasselbe Problem stoßen, das der TO hier hatte (Powershell: Send a mime encrypted email with excel file attachment).

Danke dafür!

Gruß
ANKH
Member: colinardo
colinardo Jun 16, 2014 updated at 17:36:23 (UTC)
Goto Top
Hi Ankh,
naja, der Quellcode der Bibliothek ist ja wie beschrieben auf codeproject offen verfügbar und besteht auch nur aus nativen .NET Code , d.h wer Bedenken hat, kann sich den Quellcode der Bibliothek problemlos ansehen, und auch selber kompilieren, habe ich bereits gemacht und in keinster Weise anstößige Stellen gefunden (ist ja auch nicht besonders lang). Wer will kann sich das ganze ja dann auch komplett in Powershell umsetzen.

Grüße Uwe
Member: AnkhMorpork
AnkhMorpork Jun 16, 2014 updated at 17:45:10 (UTC)
Goto Top
Hi Uwe,

ja, klar soweit. Meine Bedenken galten auch nur den etwas bedenklicheren Geistern. Ich habe da wenig Berührungsängste, und werde das auch nicht nutzen, um den Offenbarungseid zu leisten ...

Alles Gute
ANKH
Mitglied: 114757
114757 Jun 16, 2014 updated at 18:26:24 (UTC)
Goto Top
Klasse, kommt wie gerufen und klappt hervorragend face-smile

Vielen Dank auch für die Bereitstellung der DLL, das hat es mir doch ziemlich erleichtert face-smile

Gruß
jodel32
Member: LeeX01
LeeX01 Sep 26, 2020 at 12:32:21 (UTC)
Goto Top
Servus Colinardo,

ich habe gestern gesucht aber das scheint weiterhin der einzige einfache Weg zu sein um signierte Mails schicken zu können. Klappt auch gut aber meinst du es wäre möglich ein Zertifikat aus dem Zertifikatsspeicher zu benutzen? Das wäre mir lieber als die Zertifikate und Passwörter so abzulegen.

Grüße und schönes Wochenende
Member: colinardo
colinardo Sep 26, 2020 updated at 13:24:12 (UTC)
Goto Top
Zitat von @LeeX01:

Servus Colinardo,
Servus @LeeX01,
ich habe gestern gesucht aber das scheint weiterhin der einzige einfache Weg zu sein um signierte Mails schicken zu können.
Nein ist es nicht, da gibt es z.B. auch noch Mailkit und das ist mit Powershell auch hervorragend nutzbar, das sollte man im Hinblick auf den Deprecated Status von System.Net.Mail.SmtpClient sowieso in Betracht ziehen face-wink
http://www.mimekit.net/docs/html/N_MimeKit_Cryptography.htm
Klappt auch gut aber meinst du es wäre möglich ein Zertifikat aus dem Zertifikatsspeicher zu benutzen? Das wäre mir lieber als die Zertifikate und Passwörter so abzulegen.
Kannst du ganz einfach machen, Powershell bietet ja von Haus auf direkten Zugriff auf die Zertifikate an:
Das Beispiel lädt das Zertifikat mit dem Thumbprint 2B38040F17D6F9049BBC6940DA129D24658DDF89 aus dem persönlichen Speicher in die Variable
$mycert = Get-Item Cert:\CurrentUser\my\2B38040F17D6F9049BBC6940DA129D24658DDF89
Verfügbare Zertfikate kannst du dir wie gehabt mit den bekannten CMDlets dort anzeigen lassen
ls cert:\CurrentUser\my

Grüße Uwe
Member: LeeX01
LeeX01 Sep 26, 2020 at 13:30:34 (UTC)
Goto Top
Hatte mir MimeKit angeschaut aber hab immer nur was für C# gefunden und das bekomm ich dann doch nicht so einfach zum laufen. Also doch so einfach face-smile Merci!
Member: colinardo
colinardo Sep 26, 2020 updated at 13:35:11 (UTC)
Goto Top
Zitat von @LeeX01:

Hatte mir MimeKit angeschaut aber hab immer nur was für C# gefunden
Alles was unter c# läuft kannst du auch nach Powershell portieren, ist ja auch nur .NET und Powershell besteht aus dem .NET Framework face-smile
Basis Mailkit Beispiel findest du von mir hier:
E-Mail Client für Kommandozeile
Member: LeeX01
LeeX01 Sep 26, 2020 at 13:41:00 (UTC)
Goto Top
Das wollte ich machen aber der gefundene Beispielcode hatte schon im VS einige Fehler angezeigt deswegen hab ich’s dann gar nicht weiter versucht. Danke auch für den Link, schau mir an.
Member: colinardo
colinardo Dec 18, 2020, updated at Mar 30, 2024 at 10:52:44 (UTC)
Goto Top
Da hier das Interesse ja doch einigermaßen hoch an dem Thema ist , habe ich mal eine Powershell-Funktion mit der Mailkit-Bibliothek gescriptet die so gut wie sämtliche Möglichkeiten von Send-MailMessage bietet und darüber hinaus zusätzliche wie Inline-Images im HTML-Code und natürlich das signierte, verschlüsselte und kombinierte signierte+verschlüsselte Mails unterstützt.
back-to-topDownloaden könnt ihr es hier:

back-to-topmailkit_send_signed_encrypted_241025.zip


back-to-topVorschau auf die verfügbaren Parameter der Funktion


function Send-MailMessageMailkit {
    [cmdletbinding(SupportsShouldProcess=$true)]
    param(
        [parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$from,
        [parameter(mandatory=$true)][string[]]$to,
        [parameter(mandatory=$false)][string[]]$cc,
        [parameter(mandatory=$false)][string[]]$bcc,
        [parameter(mandatory=$false)][string]$subject,
        [parameter(mandatory=$false)][string]$body,
        [parameter(mandatory=$false)][switch]$bodyashtml,
        [parameter(mandatory=$false)][string[]]$attachments,
        [parameter(mandatory=$false,HelpMessage='Add body attachments like images and use them in your html body by placing "<img src="cid:{0}" /> Parameter should be a hashtable with your IDs as Keys and the attachment path as Value" ')][hashtable]$bodyresources,  
        [parameter(mandatory=$false)][ValidateSet("Low","Normal","High")][string]$priority = "Normal",  
        [parameter(mandatory=$false)][switch]$ignoreservercertificate,
        [parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$smtpserver,
        [parameter(mandatory=$false)][int]$port = 25,
        [parameter(mandatory=$false)][switch]$useSSL,
        [parameter(mandatory=$false)][pscredential]$credential,
        [parameter(mandatory=$false)][ValidateSet("None","Sign","Encrypt","Sign+Encrypt")][string]$smime_mode = "None",  
        [parameter(mandatory=$false)][X509Certificate[]]$PublicCertificates,
        [parameter(mandatory=$false)][X509Certificate]$PrivateCertificate
    )
# ...
# ..

back-to-topBeispiele für die Verwendung der Funktion


# EXAMPLE 1: Send a simple HTML E-Mail using SSL on Port 465

Send-MailMessageMailkit `
    -from 'sender@domain.tld' `  
    -to 'receiver@domain.tld' `  
    -subject 'Das ist ein Test' `  
    -body 'Hallo <strong>das ist ein Test</strong> <br>' `  
    -bodyashtml `
    -smtpserver 'smtp.domain.tld' `  
    -port 465 `
    -useSSL `
    -credential (new-Object PSCredential('<USERNAME>',(ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force))) `  
    -Verbose

# EXAMPLE 2: Send signed and encrypted message with certificates installed in local certificate store

Send-MailMessageMailkit `
    -from 'sender@domain.tld' `  
    -to 'receiver@domain.tld' `  
    -subject 'Das ist ein Test' `  
    -body 'Hallo <strong>das ist ein Test</strong> <br>' `  
    -bodyashtml `
    -smtpserver 'smtp.domain.tld' `  
    -port 465 `
    -useSSL `
    -credential (new-Object PSCredential('<USERNAME>',(ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force))) `  
    -smime_mode Sign+Encrypt `
    -PrivateCertificate (Get-Item Cert:\CurrentUser\my\DCB8E8C9BD546456C54E7A12646B1819C18A0617) `
    -PublicCertificates @(Get-Item Cert:\CurrentUser\my\DCB8E8C9BD546456C54E7A12646B1819C18A0617) `
    -Verbose

# EXAMPLE 3: Send signed message with certificates installed in local certificate store

Send-MailMessageMailkit `
    -from 'sender@domain.tld' `  
    -to 'receiver@domain.tld' `  
    -subject 'Das ist ein Test' `  
    -body 'Hallo <strong>das ist ein Test</strong> <br>' `  
    -bodyashtml `
    -smtpserver 'smtp.domain.tld' `  
    -port 465 `
    -useSSL `
    -credential (new-Object PSCredential('<USERNAME>',(ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force))) `  
    -smime_mode Sign `
    -PrivateCertificate (Get-Item Cert:\CurrentUser\my\DCB8E8C9BD546456C54E7A12646B1819C18A0617) `
    -Verbose `

# EXAMPLE 4: Send signed and encrypted message with certificates from file

Send-MailMessageMailkit `
    -from 'sender@domain.tld' `  
    -to 'receiver@domain.tld' `  
    -subject 'Das ist ein Test' `  
    -body 'Hallo <strong>das ist ein Test</strong> <br>' `  
    -bodyashtml `
    -smtpserver 'smtp.domain.tld' `  
    -port 465 `
    -useSSL `
    -credential (new-Object PSCredential('<USERNAME>',(ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force))) `  
    -smime_mode Sign `
    -PrivateCertificate (Get-Item Cert:\CurrentUser\my\DCB8E8C9BD546456C54E7A12646B1819C18A0617) `
    -smime_mode Sign+Encrypt `
    -PrivateCertificate ([X509Certificate]::new("C:\Zertifikate\private_cert.pfx","<YOURPASSWORD>",[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)) `  
    -PublicCertificates ([X509Certificate]::new("C:\Zertifikate\empfänger.cer")) `  
    -Verbose `

# EXAMPLE 5: Send Message with attachments and inline attachments

Send-MailMessageMailkit `
    -from 'sender@domain.tld' `  
    -to 'receiver@domain.tld' `  
    -subject Test `
    -body 'Hallo <strong>das ist ein</strong> Test <br><img src="cid:MyID1" />' `  
    -bodyashtml `
    -smtpserver 'smtp.domain.tld' `  
    -port 465 `
    -useSSL `
    -attachments 'D:\test.txt' `  
    -credential (New-Object PSCredential('<USERNAME>',(ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force))) `  
    -bodyresources @{'MyID1' = "D:\Bilder\inline_image.jpg"} `  
    -Verbose

Viel Spaß damit
Grüße Uwe
Member: colinardo
colinardo Dec 18, 2020 updated at 14:44:51 (UTC)
Goto Top
Klappt hier einwandfrei, Problem muss wohl auf deiner Seite liegen. Habe das Teil gerade noch nachträglich als *.zip gepackt da sonst einige Browser/Suiten allergisch auf die *.ps1 Extension des Links reagieren.
Member: Alaettin
Alaettin Jul 19, 2021 at 13:26:32 (UTC)
Goto Top
Hallo Uwe

wie kann ich mit dem Script den Inhalt eines Ordners als Anhang mitsenden?
Sobald Ich versuche mehr als Einen Anhang zu versenden bleibt der Script
AUSFÜHRLICH: Creating smtp client.
AUSFÜHRLICH: Connecting to smtp server '*'.
AUSFÜHRLICH: Authentification with smtp server '
*'.
AUSFÜHRLICH: Creating mail message.

stehen!

Vielen Dank
Member: colinardo
colinardo Jul 20, 2021 updated at 07:19:51 (UTC)
Goto Top
Zitat von @Alaettin:
wie kann ich mit dem Script den Inhalt eines Ordners als Anhang mitsenden?
Servus @Alaettin, willkommen auf Administrator.de!
Das ist kein Problem, der $attachments Parameter akzeptiert ein String-Array [string[]] das du mittels Get-ChildItem so automatisch mit allen Dateien eines Ordners füllen kannst
Send-MailMessageMailkit `
    -from 'sender@domain.tld' `  
    -to 'receiver@domain.tld' `  
    -subject 'Test' `  
    -body 'Hallo das ist ein Test' `  
    -port 587 `
    -smtpserver 'smtp.domain.tld' `  
    -attachments (Get-ChildItem 'D:\Ordner' -File | select -Expand Fullname) `  
    -Verbose `
    -credential (new-Object PSCredential('**********',(ConvertTo-SecureString '********' -AsPlainText -Force)))  
Klappt hier einwandfrei.

Grüße Uwe
Member: Alaettin
Alaettin Jul 20, 2021 at 08:49:48 (UTC)
Goto Top
Hallo Uwe
Herzlichen dank für die Info!
Hast du auch eine Idee wie ich das Script dazu bringen kann dass er nur dann eine mail versendet wenn auch in dem Ordner Daten sind und diese nach dem Versand ein Archivordner verschiebt?

Danke und Gruß
Member: colinardo
colinardo Jul 20, 2021 updated at 09:11:07 (UTC)
Goto Top
Zitat von @Alaettin:
Hast du auch eine Idee wie ich das Script dazu bringen kann dass er nur dann eine mail versendet wenn auch in dem Ordner Daten sind
if (Get-ChildItem 'D:\Ordner' -File){  
   # .......
}

und diese nach dem Versand ein Archivordner verschiebt?
Get-ChildItem 'D:\Ordner' -File | move-item -Destination 'D:\Archiv'  

=> Powershell Link-Leitfaden für Anfänger
Member: Alaettin
Alaettin Jul 20, 2021 at 09:28:52 (UTC)
Goto Top
Super, danke dir funktioniert einwandfrei
Member: Alaettin
Alaettin Jul 20, 2021 at 11:08:39 (UTC)
Goto Top
Hallo Uwe,
jetzt bekomme ich diese Fehlermeldung!
Exception calling "Connect" with "3" argument(s): "An error occurred while attempting to establish an SSL or TLS connection.  
The host name did not match the name given in the server's SSL certificate.  
"  
At C:\PShell\Mailversand.ps1:164 char:13
+             throw $_.Exception.Message
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Exception calli...certificate.
":String) , RuntimeException  
    + FullyQualifiedErrorId : Exception calling "Connect" with "3" argument(s): "An error occurred while attempting to establish an SSL or TLS connection.  
The host name did not match the name given in the server's SSL certificate.  
"  
Member: colinardo
colinardo Jul 20, 2021 updated at 12:43:20 (UTC)
Goto Top
The host name did not match the name given in the server's SSL certificate.
Die Fehlermeldung ist selbsterklärend. Benutze den richtigen Hostnamen der im Zertifikat des Servers steht den du ansprichst oder benutze den Switch-Parameter -ignoreservercertificate um das Zertifkat zu ignorieren (nicht empfohlen) face-wink.
Member: Alaettin
Alaettin Jul 20, 2021 at 12:52:00 (UTC)
Goto Top
Wo muß ich den Parameter einsetzen?
Member: colinardo
colinardo Jul 20, 2021 updated at 12:56:29 (UTC)
Goto Top
Zitat von @Alaettin:

Wo muß ich den Parameter einsetzen?

Ernsthaft?? An die Funktion ... Steht doch in den Parametern der Funktion, man müsste sie nur mal lesen face-wink.
Send-MailMessageMailkit  ...... -ignoreservercertificate
Member: Alaettin
Alaettin Jul 20, 2021 at 13:01:58 (UTC)
Goto Top
Super Vielen Dank!
Member: mudshark1309
mudshark1309 Jan 14, 2022 at 09:16:58 (UTC)
Goto Top
Hallo Uwe,

das Versenden klappt bei mir ohne Signieren einwandfrei.

Wenn ich die Parameter
 -smime_mode Sign `
     -PrivateCertificate (Get-Item Cert:\CurrentUser\TrustedPeople\59F5E10B1AF686FD71CA0F99462C6DDAC5745948)  `
     -PublicCertificates @(Get-Item Cert:\CurrentUser\TrustedPeople\59F5E10B1AF686FD71CA0F99462C6DDAC5745948)   `

einschalte, erhalte ich folgende Fehlermeldung:

Exception calling ".ctor" with "1" argument(s): "Invalid provider type specified.  
"  
At D:\temp\SendMail\SendMailkit.ps1:172 char:13
+             throw $_.Exception.Message
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Exception calli...e specified.
":String) , RuntimeException  
    + FullyQualifiedErrorId : Exception calling ".ctor" with "1" argument(s): "Invalid provider type specified.  

Die Exception tritt an der Code-Stelle

'Sign' {  
                            Write-Verbose "SMIME: Signing message."  
                            $mail.body = [MimeKit.Cryptography.ApplicationPkcs7Mime]::Sign([MimeKit.Cryptography.CmsSigner]::new($PrivateCertificate),$mail.Body)
                        }

auf.

Das Zertifikat ist laut certmgr.msc geeignet für
Digital Signature, Non-Repudiation, Key Encipherment (e0)

Hast Du eine Idee?

Vielen Dank,
Jürgen
Member: colinardo
colinardo Jan 14, 2022 updated at 11:32:43 (UTC)
Goto Top
Servus Jürgen,
Wenn ich die Parameter
 -smime_mode Sign `
> -PrivateCertificate (Get-Item Cert:\CurrentUser\TrustedPeople\59F5E10B1AF686FD71CA0F99462C6DDAC5745948) `
> -PublicCertificates @(Get-Item Cert:\CurrentUser\TrustedPeople\59F5E10B1AF686FD71CA0F99462C6DDAC5745948) `
einschalte, erhalte ich folgende Fehlermeldung:
Ich sehe hier mehrere Fehler, zum einen ist der Parameter -PublicCertificates beim Signieren überflüssig da wir hier ja nichts verschlüsseln. Zum anderen nutzt du ein Zertifikat im Store TrustedPeople, das dort wohl vermutlich ohne private Key abgelegt ist, oder für das eine erweiterte Sicherheit aktiviert wurde. Für eine Signatur ist aber ein Zertifikat mit vorhandenem private Key erforderlich. Also beim Import inkl. private Key zu importieren (also bswp. über ein *.pfx/*.p12 Container).

Hier mit einem validen Zertifikat nochmal im Test problemlos verschickt:

screenshot

Grüße Uwe
Member: mudshark1309
mudshark1309 Jan 14, 2022 at 12:29:12 (UTC)
Goto Top
Hallo Uwe,

herzlichen Dank.

Hättest Du einen Code-Schnipsel für mich, der den Import des Zertifikats
(Also beim Import inkl. private Key zu importieren (also bswp. über ein *.pfx/*.p12 Container).)
aus einer pfx.Datei skizziert?

Vielen Dank,
Jürgen
Member: colinardo
colinardo Jan 14, 2022 updated at 15:13:56 (UTC)
Goto Top
Zitat von @mudshark1309:
Hättest Du einen Code-Schnipsel für mich, der den Import des Zertifikats
(Also beim Import inkl. private Key zu importieren (also bswp. über ein *.pfx/*.p12 Container).)
aus einer pfx.Datei skizziert?
Im einfachsten Fall Doppelklick auf die *.pfx, Passwort eingeben und in den personal store importieren.

Wenn du das mit der Powershell machen willst, das geht natürlich auch, hier ein Beispiel um ein *.p12/*.pfx Container in den persönlichen Certificate-Store zu importieren, Pfad und Passwort des Containers natürlich anpassen.
# import *.pfx/*.p12 container to local trust store
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new('My','CurrentUser')  
$store.Open('ReadWrite')  
$store.Add([X509Certificate]::new("C:\Zertifikate\test.p12",'MyPassw0rd',[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable))  
$store.Close()
Grüße Uwe
Member: mudshark1309
mudshark1309 Jan 18, 2022 at 10:48:44 (UTC)
Goto Top
Hallo Uwe,

vielen Dank für Deine Unterstützung face-smile

Leider hakt es weiterhin an der gleichen Stelle.
Ich habe das Zertifikat im Store unter CurrentUser\My abgelegt und
lade es über den entsprechenden Skript-Parameter von dort erfolgreich
in die Variable $PrivateCertificate.

Wenn ich dann allerdings in die Code-Zeile zum Signieren hinein-steppe:

$mail.body = [MimeKit.Cryptography.ApplicationPkcs7Mime]::Sign([MimeKit.Cryptography.CmsSigner]::new($PrivateCertificate),$mail.Body)

wird die für mich nicht entschlüsselbare Exeption geworfen:

Ausnahme beim Aufrufen von ".ctor" mit 1 Argument(en):  "Ungültigen Anbietertyp angegeben  
"  
In C:\Users\st1g\Downloads\Sent signed Mail\MailKit.ps1:203 Zeichen:13
+             throw $_.Exception.Message
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Ausnahme beim A...yp angegeben
":String) , RuntimeException  
    + FullyQualifiedErrorId : Ausnahme beim Aufrufen von ".ctor" mit 1 Argument(en):  "Ungültigen Anbietertyp angegeben  

Das Zertifikat kann ich über Outlook erfolgreich zum Signieren verwenden.

certutil bemerkt u.a. folgendes zum von mir verwendeten Zertifikat:

 Anbieter = Microsoft Software Key Storage Provider
  Anbietertyp = 0
  RSA
  Export Policy = 1
    NCRYPT_ALLOW_EXPORT_FLAG -- 1
  Algorithm Group: RSA
  Algorithm Name: RSA
  Length: 2048 (0x800)
  Lengths:
    dwMinLength = 512 (0x200)
    dwMaxLength = 16384 (0x4000)
    dwIncrement = 8 (0x8)
    dwDefaultLength = 1024 (0x400)
  Block Length: 256 (0x100)
  Export Policy: 1 (0x1)
    NCRYPT_ALLOW_EXPORT_FLAG -- 1

  Key Usage: 16777215 (0xffffff)
    NCRYPT_ALLOW_DECRYPT_FLAG -- 1
    NCRYPT_ALLOW_SIGNING_FLAG -- 2
    NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
    NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
    NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)

  Virtual Iso: 0 (0x0)
  Per Boot Key: 0 (0x0)
  Key Usage = ffffff (16777215)
    NCRYPT_ALLOW_DECRYPT_FLAG -- 1
    NCRYPT_ALLOW_SIGNING_FLAG -- 2
    NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4
    NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8
    NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)
Der private Schlüssel eignet sich nicht zum Nur-Text-Export.
Verschlüsselungstest wurde durchgeführt
CertUtil: -dump-Befehl wurde erfolgreich ausgeführt.

Hast Du noch einen Tipp für mich?

Vielen Dank,
Jürgen
Member: colinardo
colinardo Jan 18, 2022 updated at 12:00:00 (UTC)
Goto Top
Hast Du noch einen Tipp für mich?
Ja, die vom Skript zur Zeit genutzte .NET DLL von Mimekit für .NET 4.52 supported keinen CNG Storage Provider (Microsoft Software Key Storage Provider) willst du per CNG geschützte Schlüssel benutzen musst du dir die DLLs für >= .NET 4.6 bei Nuget herunterladen und ersetzen.

(#edit#: Ist im Skript nun auf Nutzung von .NET 4.6 hochgezogen)
# ....
        Load-NugetAssembly 'https://www.nuget.org/api/v2/package/Portable.BouncyCastle/1.9.0' -name 'BouncyCastle.Crypto.dll' -zipinternalpath 'lib/net40/BouncyCastle.Crypto.dll' -EA Stop  
        Load-NugetAssembly 'https://www.nuget.org/api/v2/package/System.Buffers/4.5.1' -name 'System.Buffers.dll' -zipinternalpath 'lib/net461/System.Buffers.dll' -EA Stop  
        Load-NugetAssembly 'https://www.nuget.org/api/v2/package/System.Data.SQLite.x64/1.0.115.5' -name 'System.Data.SQLite.dll' -zipinternalpath 'lib/net46/System.Data.SQLite.dll' -EA Stop  
        Load-NugetAssembly 'https://www.nuget.org/api/v2/package/MimeKit/3.1.0' -name 'MimeKit.dll' -zipinternalpath 'lib/net46/MimeKit.dll' -EA Stop  
        Load-NugetAssembly 'https://www.nuget.org/api/v2/package/MailKit/3.1.0' -name 'MailKit.dll' -zipinternalpath 'lib/net46/MailKit.dll' -EA Stop  
# ....

Alternativ das Cert mit dem Enhanced Classic Provider einbinden
https://docs.microsoft.com/en-us/windows/win32/seccertenroll/cryptoapi-c ...

Grüße Uwe
Member: Aburcubur
Aburcubur Mar 15, 2023 at 11:03:22 (UTC)
Goto Top
Hallo Uwe
Ich bekomme die Fehlermeldung beim Zertifikat
 + FullyQualifiedErrorId : Exception calling ".ctor" with "1" argument(s): "Key not valid for use in specified state.  

Hast du einen Lösungsvorschlag oder was ich überprüfen kann?

Vielen dank für deine mühe
Member: colinardo
colinardo Mar 15, 2023, updated at Mar 16, 2023 at 11:31:36 (UTC)
Goto Top
Zitat von @Aburcubur:
Ich bekomme die Fehlermeldung beim Zertifikat
 + FullyQualifiedErrorId : Exception calling ".ctor" with "1" argument(s): "Key not valid for use in specified state.  
Servus @Aburcubur, willkommen auf Administrator.de!
Entweder dein angegebenes Zertifikat hat keinen private Key, oder der Key ist beim Import nicht "als Exportierbar" markiert worden, oder die KeyUsage Eigenschaften für das Signieren/Verschlüsseln von Mails sind im Zertifikat nicht vorhanden.

Grüße Uwe
Member: Aburcubur
Aburcubur Mar 16, 2023 at 09:25:20 (UTC)
Goto Top
Hallo Uwe
Das Zertifikat hat einen Privaten Key und wird mir auch angezeigt!
key