我需要在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);
}
答案 0 :(得分: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
需要使用原始内容构建,然后解码签名以执行验证。