0

以前、Application-A は C++ にあり、メッセージは C++ の crypto API 関数を使用して Application-B に送信する前に署名されていました。これは、 http://msdn.microsoft.com/en-us/library/で説明されている例とまったく同じです。 windows/desktop/aa382372%28v=vs.85%29.aspx .

このメッセージは、C++ の Crypto API 関数を使用して Application-B によって再度検証されました (上記の例では、署名済みのメッセージを検証する方法について再度説明しています)。

現在、古い C++ Application-A を C# に変換/移行しています。C# でP-Invoke を使用してメッセージに署名する方法を既に見つけました。署名されたメッセージが Application-B (C++ CryptVerifySignatureMessage を使用) によって検証されると、すべて正常に動作します。例はhttp://blogs.msdn.com/b/alejacma/archive/2008/02/21/how-to-sign-a-message-and-verify-a-message-signature-c.aspxにあります。 .

@CodeInChaosがコメントで述べたように、相互運用作業をフレームワークに任せたい (P-Invoke や BountyCastle のような他のサードパーティの実装を使用しない)。

それで、.netがメッセージに署名するためのAPIを提供しているかどうかを知りたいです(学習の観点からも)。

ノート:

私はすでに.Netが提供する暗号ラッパーAPI RSACryptoServiceProviderを試しました。

    private byte[] SignData(byte[] data, string certThumbPrint)
    {
        X509Certificate2 cert = GetCertificate(); // finds the certificate with thumbprint
        RSACryptoServiceProvider rsaCryptoServiceProvider = (RSACryptoServiceProvider)cert.PrivateKey;
        return rsaCryptoServiceProvider.SignData(data, new SHA1CryptoServiceProvider());
    }

しかし、C++ の CryptSignMessage と C# の RSACryptoServiceProvider.SignData() メソッドの戻り値 (バイト配列) に大きな違いが見つかりました。

• CryptSignMessage: CryptSignMessage 関数は、指定されたコンテンツのハッシュを作成し、ハッシュに署名してから、元のメッセージ コンテンツと署名付きハッシュの両方をエンコードします。

• RSA.SignData: 指定されたハッシュ アルゴリズムを使用して、指定されたバイト配列のハッシュ値を計算し、結果のハッシュ値に署名します。

この違いにより、Application-B がメッセージを検証すると、「無効な署名」というエラーがスローされます。

したがって、.net が提供するこの RSACryptoServiceProvider タイプは使用できません。.NET API を使用して同じことを達成する他の方法はありますか? (.net API を使用する場合、出力バイト配列は、前述の PInvoke の例を使用する場合の出力のバイト配列と類似している必要があります) そのため、Application-B は問題なく動作します。

どんな助けでも大歓迎です。

4

1 に答える 1

2

長い研究の後、私はそれを行う方法を見つけました。他の誰かが C# の証明書を使用して PKCS7 形式を使用してメッセージに署名する方法を探している場合は、ここにあります。

    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, which has all the needed
        //  characteristics of the signer.
        CmsSigner cmsSigner = new CmsSigner(signerCert);

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

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

リンクhttp://msdn.microsoft.com/en-us/library/ms180961%28v=vs.85%29.aspxから情報を見つけました。

于 2014-04-28T05:23:12.097 に答える