Подписывать данные с использованием формата на основе CMS в UWP

Мне нужно передать данные между службой 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);
}

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 должен быть создан с исходным содержимым, а затем декодировать подпись для выполнения проверки.

Другие вопросы по тегам