2016-06-14 18 views
1

我需要在WCF服務和UWP應用程序之間傳輸數據。因此,我在收到數據後簽署並驗證數據。我有個問題。簽名的數據導致WCF是UWP應用差異(當然,我無法驗證數據)這是我的源代碼。在UWP中使用基於CMS的格式簽名數據

// 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需要用原始內容構建,然後解碼簽名以執行驗證。