2016-06-14 3 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이 원래 내용으로 구성되어야하고 확인을 수행하기 위해 서명을 디코딩해야한다는 것을 이해하는 것이 었습니다.

관련 문제