在 UWP 中使用基于 CMS 的格式对数据进行签名 [英] Sign data using CMS based format in UWP

查看:21
本文介绍了在 UWP 中使用基于 CMS 的格式对数据进行签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 WCF 服务和 UWP 应用之间传输数据.所以我在收到数据后对数据进行签名和验证.我有个问题.WCF中的签名数据结果是UWP app中的差异.(当然,我无法验证数据)这是我的源代码:

I need to transfer data between WCF service and UWP app. So I sign and verify data after receive data. I have a problem. The signed data result in WCF is differences in UWP app.(Of course, I can't verify data) This is my source code:

// WCF
private String Sign(string Message)
{
    ContentInfo cont = new ContentInfo(Encoding.UTF8.GetBytes(Message));
    SignedCms signed = new SignedCms(cont, true);
    _SignerCert = new X509Certificate2("Path", "Password");
    CmsSigner signer = new CmsSigner(_SignerCert);
    signer.IncludeOption = X509IncludeOption.None;
    signed.ComputeSignature(signer);
    return Convert.ToBase64String(signed.Encode());
}

//UWP
public static async Task<String> Sign(String Message)
{
    StorageFolder appInstalledFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    var CerFile = await appInstalledFolder.GetFileAsync(@"Assets\PAYKII_pkcs12.p12");
    var CerBuffer = await FileIO.ReadBufferAsync(CerFile);
    string CerData = CryptographicBuffer.EncodeToBase64String(CerBuffer);

    await CertificateEnrollmentManager.ImportPfxDataAsync
        (CerData, "Password",
        ExportOption.NotExportable,
        KeyProtectionLevel.NoConsent,
        InstallOptions.None,
        "RASKey2");

    var Certificate = (await CertificateStores.FindAllAsync(new CertificateQuery() { FriendlyName = "RASKey2" })).Single();

    IInputStream pdfInputstream;
    InMemoryRandomAccessStream originalData = new InMemoryRandomAccessStream();
    await originalData.WriteAsync(CryptographicBuffer.ConvertStringToBinary(Message,BinaryStringEncoding.Utf8));
    await originalData.FlushAsync();
    pdfInputstream = originalData.GetInputStreamAt(0);
    CmsSignerInfo signer = new CmsSignerInfo();
    signer.Certificate = Certificate;
    signer.HashAlgorithmName = HashAlgorithmNames.Sha1;
    IList<CmsSignerInfo> signers = new List<CmsSignerInfo>();

    signers.Add(signer);

    IBuffer signature = await CmsDetachedSignature.GenerateSignatureAsync(pdfInputstream, signers, null);
    return CryptographicBuffer.EncodeToBase64String(signature);
}

推荐答案

我偶然发现了您的帖子,因为我想实现非常相似的目标:在 UWP 应用中签署消息并在我的 WCF 服务中验证签名.阅读完http://www.codeproject.com/Tips/679142/How-to-sign-data-with-SignedCMS-and-signature-check,我终于成功了(使用分离的签名,即你需要有用于验证的原始消息):

I stumbled over your post, because I wanted to achieve something very similar: sign a message in an UWP app and verifying the signature in my WCF Service. After reading http://www.codeproject.com/Tips/679142/How-to-sign-data-with-SignedCMS-and-signature-chec, I finally managed to make this fly (with a detached signature, ie you need to have the original message for verification):

UWP:

public async static Task<string> Sign(Windows.Security.Cryptography.Certificates.Certificate cert, string messageToSign) {
    var messageBytes = Encoding.UTF8.GetBytes(messageToSign);
    using (var ms = new MemoryStream(messageBytes)) {
        var si = new CmsSignerInfo() {
            Certificate = cert,
            HashAlgorithmName = HashAlgorithmNames.Sha256
        };

        var signature = await CmsDetachedSignature.GenerateSignatureAsync(ms.AsInputStream(), new[] { si }, null);
        return CryptographicBuffer.EncodeToBase64String(signature);
    }
}

WCF:

public static bool Verify(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, string messageToCheck, string signature) {
    var retval = false;

    var ci = new ContentInfo(Encoding.UTF8.GetBytes(messageToCheck));
    var cms = new SignedCms(ci, true);
    cms.Decode(Convert.FromBase64String(signature));

    // Check whether the expected certificate was used for the signature.
    foreach (var s in cms.SignerInfos) {
        if (s.Certificate.Equals(cert)) {
            retval = true;
            break;
        }
    }

    // The following will throw if the signature is invalid.
    cms.CheckSignature(true);

    return retval;
}

我的诀窍是理解桌面SignedCms需要用原始内容构建,然后对签名进行解码以执行验证.

The trick for me was to understand that the desktop SignedCms needs to be constructed with the original content and then decode the signature to perform the verification.

这篇关于在 UWP 中使用基于 CMS 的格式对数据进行签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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