2016-06-14 76 views
1

Ich muss Daten zwischen WCF-Dienst und UWP-App übertragen. So signiere und verifiziere ich Daten nach Empfangsdaten. Ich habe ein Problem. Die signierten Daten führen in WCF Unterschiede in UWP App ist (Natürlich kann ich die Daten nicht verifizieren) Dies ist mein Quellcode.Signieren von Daten mit CMS-basierten Format in 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()); 
} 

und

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

Antwort

1

ich über Ihren Beitrag gestolpert, weil ich etwas sehr ähnliches erreichen wollte: signiere eine Nachricht in einer UWP-App und überprüfe die Signatur in meinem WCF-Dienst. Nach der Lektüre http://www.codeproject.com/Tips/679142/How-to-sign-data-with-SignedCMS-and-signature-chec gelang es mir endlich diese Fliege zu machen (mit einem frei stehenden Unterschrift, dh Sie können die ursprüngliche Nachricht zur Überprüfung haben müssen):

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

Der Trick für mich war zu verstehen, dass der Desktop SignedCms mit dem ursprünglichen Inhalt erstellt werden und dann die Signatur dekodieren muss, um die Verifizierung durchzuführen.