【问题标题】:Sign data using CMS based format in UWP在 UWP 中使用基于 CMS 的格式对数据进行签名
【发布时间】:2016-10-15 08:21:19
【问题描述】:

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

// 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);
}

【问题讨论】:

    标签: c# wcf uwp sign pkcs#7


    【解决方案1】:

    我偶然发现了您的帖子,因为我想实现非常相似的目标:在 UWP 应用程序中签署消息并在我的 WCF 服务中验证签名。看完http://www.codeproject.com/Tips/679142/How-to-sign-data-with-SignedCMS-and-signature-chec,终于搞定了(带分离签名,即需要有原消息进行验证):

    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需要用原始内容构建,然后解码签名以执行验证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      相关资源
      最近更新 更多