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-ID: 241025

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

Ausgedruckt am: 23.11.2024 um 23:11 Uhr

AnkhMorpork
AnkhMorpork 16.06.2014 um 19:18:54 Uhr
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
colinardo
colinardo 16.06.2014 aktualisiert um 19:36:23 Uhr
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
AnkhMorpork
AnkhMorpork 16.06.2014 aktualisiert um 19:45:10 Uhr
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
114757
114757 16.06.2014 aktualisiert um 20:26:24 Uhr
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
LeeX01
LeeX01 26.09.2020 um 14:32:21 Uhr
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
colinardo
colinardo 26.09.2020 aktualisiert um 15:24:12 Uhr
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
LeeX01
LeeX01 26.09.2020 um 15:30:34 Uhr
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!
colinardo
colinardo 26.09.2020 aktualisiert um 15:35:11 Uhr
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
LeeX01
LeeX01 26.09.2020 um 15:41:00 Uhr
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.
colinardo
colinardo 18.12.2020, aktualisiert am 30.03.2024 um 11:52:44 Uhr
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
colinardo
colinardo 18.12.2020 aktualisiert um 15:44:51 Uhr
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.
Alaettin
Alaettin 19.07.2021 um 15:26:32 Uhr
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
colinardo
colinardo 20.07.2021 aktualisiert um 09:19:51 Uhr
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
Alaettin
Alaettin 20.07.2021 um 10:49:48 Uhr
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ß
colinardo
colinardo 20.07.2021 aktualisiert um 11:11:07 Uhr
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
Alaettin
Alaettin 20.07.2021 um 11:28:52 Uhr
Goto Top
Super, danke dir funktioniert einwandfrei
Alaettin
Alaettin 20.07.2021 um 13:08:39 Uhr
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.  
"  
colinardo
colinardo 20.07.2021 aktualisiert um 14:43:20 Uhr
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.
Alaettin
Alaettin 20.07.2021 um 14:52:00 Uhr
Goto Top
Wo muß ich den Parameter einsetzen?
colinardo
colinardo 20.07.2021 aktualisiert um 14:56:29 Uhr
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
Alaettin
Alaettin 20.07.2021 um 15:01:58 Uhr
Goto Top
Super Vielen Dank!
mudshark1309
mudshark1309 14.01.2022 um 10:16:58 Uhr
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
colinardo
colinardo 14.01.2022 aktualisiert um 12:32:43 Uhr
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
mudshark1309
mudshark1309 14.01.2022 um 13:29:12 Uhr
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
colinardo
colinardo 14.01.2022 aktualisiert um 16:13:56 Uhr
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
mudshark1309
mudshark1309 18.01.2022 um 11:48:44 Uhr
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
colinardo
colinardo 18.01.2022 aktualisiert um 13:00:00 Uhr
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
Aburcubur
Aburcubur 15.03.2023 um 12:03:22 Uhr
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
colinardo
colinardo 15.03.2023, aktualisiert am 16.03.2023 um 12:31:36 Uhr
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
Aburcubur
Aburcubur 16.03.2023 um 10:25:20 Uhr
Goto Top
Hallo Uwe
Das Zertifikat hat einen Privaten Key und wird mir auch angezeigt!
key