Verfahrensweise: Signieren von Nachrichten durch einen Signierer

In diesem Beispiel wird eine CMS/PKCS #7-signierte Nachricht unter Verwendung von System.Security.Cryptography.Pkcs erstellt. Die Nachricht wird von einem einzelnen Signierer signiert. Die Signatur der Nachricht wird anschließend überprüft.

Beispiel

In diesem Beispiel werden die folgenden Klassen verwendet:

Für das folgende Beispiel ist es erforderlich, dass der Zertifikatspeicher "My" ein Zertifikat mit öffentlichem Schlüssel mit dem Antragstellernamen "MessageSigner1" enthält und dass der zugeordnete private Schlüssel vorhanden ist.

NoteHinweis:

Dieses Beispiel dient nur der Veranschaulichung. In Produktionsumgebungen kann ein anderes Modell verwendet werden, in dem Absender und Empfänger der Nachricht in verschiedenen Prozessen mit ihren eindeutigen Anmeldeinformationen des öffentlichen Schlüssels ausgeführt werden.

Richten Sie dieses Beispiel mithilfe des Dienstprogramms Makecert.exe ein; dies ist nur eine von vielen Möglichkeiten. Certificate Creation Tool (Makecert.exe) ist ein komfortables Dienstprogramm zum Generieren von Testzertifikaten. In einer Produktionsumgebung werden Zertifikate von einer Zertifizierungsstelle generiert.

Mithilfe des folgenden Makecert-Befehls werden die erforderlichen Zertifikate mit öffentlichem Schlüssel und die privaten Schlüssel generiert.

Makecert -n "CN=MessageSigner1" -ss My

// Copyright (c) Microsoft Corporation.  All rights reserved.
#region Using directives

using System;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text;

#endregion

namespace SigningAMessageByOneSigner
{
    class SignedCmsSingleSigner
    {
        const String signerName = "MessageSigner1";

        static void Main(string[] args)
        {
            Console.WriteLine("System.Security.Cryptography.Pkcs " +
                "Sample: Single-signer signed and verified message");
            //  Original message.
            const String msg = "This is the message to be signed.";

            Console.WriteLine("\nOriginal message (len {0}): {1}  ",
                msg.Length, msg);

            //  Convert message to array of bytes for signing.
            Encoding unicode = Encoding.Unicode;
            byte[] msgBytes = unicode.GetBytes(msg);

            Console.WriteLine("\n\n------------------------------");
            Console.WriteLine("     SETUP OF CREDENTIALS     ");
            Console.WriteLine("------------------------------\n");

            X509Certificate2 signerCert = GetSignerCert();

            Console.WriteLine("\n\n----------------------");
            Console.WriteLine("     SENDER SIDE      ");
            Console.WriteLine("----------------------\n");

            byte[] encodedSignedCms = SignMsg(msgBytes, signerCert);

            Console.WriteLine("\n\n------------------------");
            Console.WriteLine("     RECIPIENT SIDE     ");
            Console.WriteLine("------------------------\n");

            if (VerifyMsg(encodedSignedCms))
            {
                Console.WriteLine("\nMessage verified");
            }
            else
            {
                Console.WriteLine("\nMessage failed to verify");
            }
        }

        //  Open the My (or Personal) certificate store and search for
        //  credentials to sign the message with. The certificate
        //  must have the subject name "MessageSigner1".
        static public X509Certificate2 GetSignerCert()
        {
            //  Open the My certificate store.
            X509Store storeMy = new X509Store(StoreName.My,
                StoreLocation.CurrentUser);
            storeMy.Open(OpenFlags.ReadOnly);

            //  Display certificates to help troubleshoot 
            //  the example's setup.
            Console.WriteLine("Found certs with the following subject " +
                "names in the {0} store:", storeMy.Name);
            foreach (X509Certificate2 cert in storeMy.Certificates)
            {
                Console.WriteLine("\t{0}", cert.SubjectName.Name);
            }

            //  Find the signer's certificate.
            X509Certificate2Collection certColl =
                storeMy.Certificates.Find(X509FindType.FindBySubjectName,
                signerName, false);
            Console.WriteLine(
                "Found {0} certificates in the {1} store with name {2}",
                certColl.Count, storeMy.Name, signerName);

            //  Check to see if the certificate suggested by the example
            //  requirements is not present.
            if (certColl.Count == 0)
            {
                Console.WriteLine(
                    "A suggested certificate to use for this example " +
                    "is not in the certificate store. Select " +
                    "an alternate certificate to use for " +
                    "signing the message.");
            }

            storeMy.Close();

            //  If more than one matching cert, return the first one.
            return certColl[0];
        }

        //  Sign the message with the private key of the signer.
        static public byte[] SignMsg(
            Byte[] msg,
            X509Certificate2 signerCert)
        {
            //  Place message in a ContentInfo object.
            //  This is required to build a SignedCms object.
            ContentInfo contentInfo = new ContentInfo(msg);

            //  Instantiate SignedCms object with the ContentInfo above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            //  Has default Detached property value false, so message is
            //  included in the encoded SignedCms.
            SignedCms signedCms = new SignedCms(contentInfo);

            //  Formulate a CmsSigner object for the signer.
            CmsSigner cmsSigner = new CmsSigner(signerCert);

            //  Sign the CMS/PKCS #7 message.
            Console.Write("Computing signature with signer subject " +
                "name {0} ... ", signerCert.SubjectName.Name);
            signedCms.ComputeSignature(cmsSigner);
            Console.WriteLine("Done.");

            //  Encode the CMS/PKCS #7 message.
            return signedCms.Encode();
        }

        //  Verify the encoded SignedCms message and return a Boolean
        //  value that specifies whether the verification was successful.
        static public bool VerifyMsg(byte[] encodedSignedCms)
        {
            //  Prepare an object in which to decode and verify.
            SignedCms signedCms = new SignedCms();

            signedCms.Decode(encodedSignedCms);

            //  Catch a verification exception if you want to
            //  advise the message recipient that 
            //  security actions might be appropriate.
            try
            {
                //  Verify signature. Do not validate signer
                //  certificate for the purposes of this example.
                //  Note that in a production environment, validating
                //  the signer certificate chain will probably
                //  be necessary.
                Console.Write("Checking signature on message ... ");
                signedCms.CheckSignature(true);
                Console.WriteLine("Done.");
            }
            catch (System.Security.Cryptography.CryptographicException e)
            {
                Console.WriteLine("VerifyMsg caught exception:  {0}",
                    e.Message);
                Console.WriteLine("Verification of the signed PKCS #7 " +
                    "failed. The message, signatures, or " +
                    "countersignatures may have been modified " +
                    "in transit or storage. The message signers or " +
                    "countersigners may not be who they claim to be. " +
                    "The message's authenticity or integrity, " +
                    "or both, are not guaranteed.");
                return false;
            }

            return true;
        }
    }
}

Siehe auch

Aufgaben

Verfahrensweise: Signieren einer Nachricht durch mehrere Signierer
Verfahrensweise: Gegensignieren einer Nachricht
Verfahrensweise: Versehen einer Nachricht mit einem Umschlag für einen Empfänger
Verfahrensweise: Versehen einer Nachricht mit einem Umschlag für mehrere Empfänger

Konzepte

Verfahrensweise: Signieren und Versehen einer Nachricht mit einem Umschlag

Footer image

Copyright © 2007 by Microsoft Corporation. Alle Rechte vorbehalten.