WinRT中有SignedCMS的替代方法吗? [英] Is there an alternative of SignedCMS in WinRT?

查看:79
本文介绍了WinRT中有SignedCMS的替代方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将.NET桌面应用程序移植到Windows应用商店应用程序时,我再次遇到麻烦...长话短说,我有一个ZIP文件,其中包含经过加密和签名的XML文件以及其中的证书.解密工作正常(或多或少),但是现在我必须取消签名" XML,并且卡住了.

And again I ran into trouble while porting a .NET Desktop App to a Windows Store App... Long story short, I have a ZIP File with an encrypted and signed XML File and a certificate in it. The decryption is working (more or less) but now I have to "unsign" the XML and I'm stuck.

在.NET App中,取消签名是通过System.Security.Cryptography.Pkcs.SignedCms完成的,但该类在WinRt中不存在(一如既往...)

In the .NET App the unsigning is done with System.Security.Cryptography.Pkcs.SignedCms but that class does not exist in WinRt (as always...)

WinRT中还有其他选择吗?

Is there any alternative in WinRT?

这是.NET App中使用的一些代码:

here is some of the code used in the .NET App:

public static byte[] CheckAndRemoveSignature(byte[] data,  X509Certificate2Collection certStore, out SignedCms out_signature)
    {
        SignedCms signedMessage = new SignedCms();
        signedMessage.Decode(data);

        if ((certStore != null) && (certStore.Count > 0))
            signedMessage.CheckSignature(certStore, true);
        else
            signedMessage.CheckSignature(true);

        out_signature = signedMessage;

        // return data without signature
        return signedMessage.ContentInfo.Content;
    }

我已经搜索了很多东西,但是我发现的唯一可以帮助我的就是这篇文章.不幸的是,标记的答案没有提供任何有用的信息:(

I already searched a lot, but the only thing I found, that could have helped me was this post. Unfortunately the marked answer does not provide any helpful information :(

Windows 8 Metro密码学-使用SignedCms Pkcs7

我非常感谢您的帮助:)

I would really appreciate some help here :)

本质问题是要从带符号的字节数组中获取原始xml数据.或者,更具体地说,我需要WinRT中这几行代码的功能

The essential problem is to get the original xml data out of the signed byte array. Or, more specifically I need the functionality of these few lines of code in WinRT

SignedCms signedMessage = new SignedCms();
signedMessage.Decode(data);
byte[] result = signedMessage.ContentInfo.Content;

我尝试了pepo的示例,但出现了MalformedContent异常

I tried the example from pepo, but I get a MalformedContent Exception

private byte[] CheckAndRemoveSignature(byte[] data)
    {
        try
        {
            // load using bouncyCastle
            CmsSignedData sig = new CmsSignedData(data);
            // var allSigsValid = VerifySignatures(sig);
            byte[] content = sig.SignedContent.GetContent() as byte[];
            return content;
        }
        catch (Exception ex)
        {
            cryptOutput.Text += "Error removing Signature: " + ex;
            return data;
        }

我收到此异常:

Org.BouncyCastle.Cms.CmsException: Malformed content. ---> System.ArgumentException: unknown object in factory: DerApplicationSpecific
at Org.BouncyCastle.Asn1.Cms.ContentInfo.GetInstance(Object obj)
at Org.BouncyCastle.Cms.CmsUtilities.ReadContentInfo(Asn1InputStream aIn)
   --- End of inner exception stack trace ---
at Org.BouncyCastle.Cms.CmsUtilities.ReadContentInfo(Asn1InputStream aIn)
at Org.BouncyCastle.Cms.CmsUtilities.ReadContentInfo(Stream input)
at Org.BouncyCastle.Cms.CmsSignedData..ctor(Byte[] sigBlock)
at TestApp.MainPage.CheckAndRemoveSignature(Byte[] data)


Desktop App中对XML文件进行签名的代码:


Code from Desktop App where the XML-File is signed:

  private byte[] signInternal(byte[] data, X509Certificate2 signatureCert, bool signatureOnly)
    {
        CAPICOM.SignedData signedData = new CAPICOM.SignedDataClass();
        CAPICOM.Utilities u = new CAPICOM.UtilitiesClass();
        signedData.set_Content(u.ByteArrayToBinaryString(data));
        GC.Collect();

        CAPICOM.Signer signer = new CAPICOM.Signer();
        signer.Options = CAPICOM.CAPICOM_CERTIFICATE_INCLUDE_OPTION.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY;

        CAPICOM.CertificateClass certClass = new CAPICOM.CertificateClass();
        certClass.Import(Convert.ToBase64String(signatureCert.Export(X509ContentType.SerializedCert)));
        signer.Certificate = certClass;

        GC.Collect();

        if (this.validateCert(signatureCert))
            return (byte[])Convert.FromBase64String(signedData.Sign(signer, signatureOnly, CAPICOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64));
        else
            return new byte[] { };
    }


解决方案

最后,事实证明编码存在很大的问题,我认为这不是值得注意的.pepo的答案正在起作用,但是我将发布我的版本,以显示如果您从zip文件夹中获取文件的话它是如何工作的:


Solution

In the end it turned out that there was a big problem with encoding, that I did not think was noteworthy. The answer from pepo is working, however I will post my version, to show how it works if you get the file from a zip folder:

// get bytes from zip
byte[] data = getFileContentAsByteArray(zipBytes, ze.FileName);
var dataString = Encoding.UTF8.GetString(data, 0, data.Length);

// check and remove signature
bool isValid;
byte[] withoutSig = CheckAndRemoveSignature(dataString, out isValid);


    private byte[] CheckAndRemoveSignature(string data, out bool isValid)
    {
        isValid = false;

        // using bouncyCastle
        try
        {
            var bytes = Convert.FromBase64String(data);

            // assign data to CmsSignedData                  
            CmsSignedData sig = new CmsSignedData(bytes);

            // check if signature is valid
            var allSigsValid = VerifySignaturesBC(sig);
            if (allSigsValid.Equals(true)) { isValid = true; }

            // get signature from cms
            byte[] content = sig.SignedContent.GetContent() as byte[];

            return content;
        }
        catch (Exception ex) { cryptOutput.Text += "Error in 'BouncyCastle unsign' " + ex; return null; }
    }

推荐答案

基于注释,我了解您拥有PKCS#7结构(SignedCms),该结构的内容为XmlDocument.

Based on comments I understand that you have a PKCS#7 structure (SignedCms) and the content of that structure is XmlDocument.

由于WinRT API中没有SignedCms,因此您有两种选择.您可以使用某些ASN.1库并手动解析PKCS#7以查找内容,也可以使用已实现SignedCms并可以解析此信任关系的BouncyCastle.您要求使用bouncyCastle的示例.在这里.

Because there is no SignedCms in WinRT API you have two choices. Either use some ASN.1 library and parse PKCS#7 manually looking for content or use i.e. BouncyCastle which has SignedCms implemented and can parse that strusture. You asked for an example using bouncyCastle. Here it is.

using Org.BouncyCastle.Cms;
using Org.BouncyCastle.X509.Store;
using System.Collections;
using System.Security.Cryptography.Pkcs;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            // make some pkcs7 signedCms to work on
            SignedCms p7 = new SignedCms(new System.Security.Cryptography.Pkcs.ContentInfo(new byte[] { 0x01, 0x02 }));
            p7.ComputeSignature(new CmsSigner(), false);

            // encode to get signedCms byte[] representation
            var signedCms = p7.Encode();

            // load using bouncyCastle
            CmsSignedData sig = new CmsSignedData(signedCms);

            var allSigsValid = VerifySignatures(sig);

            byte[] content = sig.SignedContent.GetContent() as byte[];
        }

        // taken from bouncy castle SignedDataTest.cs
        private static bool VerifySignatures(
            CmsSignedData sp)
        {
            var signaturesValid = true;
            IX509Store x509Certs = sp.GetCertificates("Collection");
            SignerInformationStore signers = sp.GetSignerInfos();

            foreach (SignerInformation signer in signers.GetSigners())
            {
                ICollection certCollection = x509Certs.GetMatches(signer.SignerID);

                IEnumerator certEnum = certCollection.GetEnumerator();
                certEnum.MoveNext();
                Org.BouncyCastle.X509.X509Certificate cert = (Org.BouncyCastle.X509.X509Certificate)certEnum.Current;

                signaturesValid &= signer.Verify(cert);
            }
            return signaturesValid;
        }
    }
}

对于ASN.1库,我只使用了具有ASN.1解析器或

As for the ASN.1 library, I have only worked with bouncyCastle which has ASN.1 parser or ASN.1 editor which is a very useful GUI application for showing structure of PKCS#7, certificates etc. So I can recommend only those two.

这篇关于WinRT中有SignedCMS的替代方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆