2016-06-21 14 views
0

Ich muss eine digitale Signatur als Parameter an einen externen Webservice senden.Fehler bei der digitalen Signaturprüfung für den Zugriff auf den Webservice

Die Schritte gemäß Dokumentation zu erstellen ist:

  1. erstellen DOM Darstellung der XML Daten
  2. erstellen canonicalised Darstellung der DOM Daten. Die kanonisierte Darstellung sollte der in http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments beschriebenen Form folgen;
  3. Erstellen Sie die Signatur RSA Verschlüsselung der SHA1 Digest der kanonisierten Darstellung. Die Signatur wird mit dem privaten Schlüssel des Teilnehmers verschlüsselt.
  4. Encode die binäre Signatur in einen Base64-codierten String
  5. Platz der Signatur Zeichenfolge in der Nachricht SOAPReqDigSig Elemente;
  6. Speichern Sie die XML-Daten so, wie sie später benötigt werden, um die Nichtabstreitbarkeit der übermittelten XML-Daten zu unterstützen.

Ich habe den folgenden Code verwendet:

private string SignXML(X509Certificate2 Cert, string data) 
    { 
     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.PreserveWhitespace = false; 
     xmlDoc.LoadXml(data); 

     XmlDsigC14NWithCommentsTransform t = new XmlDsigC14NWithCommentsTransform(); 
     t.LoadInput(xmlDoc); 
     Stream s = (Stream)t.GetOutput(typeof(Stream)); 

     SHA1 sha1 = SHA1.Create(); 
     byte[] hash = sha1.ComputeHash(s); 


     RSACryptoServiceProvider rsaKey = 
     (RSACryptoServiceProvider)Cert.PrivateKey; 
     RSAParameters rsaPrivateParams = rsaKey.ExportParameters(true); 
     rsaKey.ImportParameters(rsaPrivateParams); 
     byte[] signature = rsaKey.Encrypt(hash, false); 

     return Convert.ToBase64String(signature); 
    } 

Aber die Antwort von der WebService sagt Überprüfung der digitalen Signatur Fehler.

ist der obige Code laut der Beschreibung in der Dokumentation? Wie würde ich überprüfen, ob die digitale Signatur gültig ist? Gibt es ein Online-Tool?

[Beitrag wie folgt bearbeitet] Ich habe versucht, Folgendes zu verwenden. Ich habe die Signatur verifiziert und sie ist wahr. Scheitert aber am Webservice-Ende. Was ist der Unterschied zwischen signData, signHash und der rsaPKCsignatureformatter-Klasse createsignature-Methode?

 var document = Encoding.UTF8.GetBytes(Reqdata); 

     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.PreserveWhitespace = false; 
     xmlDoc.LoadXml(Reqdata); 

     //trial with XmlDsigC14NWithCommentsTransform class 
     XmlDsigC14NWithCommentsTransform t = new XmlDsigC14NWithCommentsTransform(); 
     t.LoadInput(xmlDoc); 
     Stream s = (Stream)t.GetOutput(typeof(Stream)); 

     //trial with SignedXML class 
     SignedXml signedXml = new SignedXml(xmlDoc); 
     signedXml.SignedInfo.CanonicalizationMethod = 
     SignedXml.XmlDsigC14NWithCommentsTransformUrl; 
     document = Encoding.UTF8.GetBytes(signedXml.ToString()); 

     byte[] hashedDocument; 

     using (var sha1 = SHA1.Create()) 
     { 
      //hashedDocument = sha1.ComputeHash(document); 
      hashedDocument = sha1.ComputeHash(s); 
     } 

     var digitalSignature = new DigitalSignature(); 
     digitalSignature.AssignNewKey(); 

     byte[] signature = digitalSignature.SignData(hashedDocument); 
     string finalsignature = Convert.ToBase64String(signature) ; 
     byte[] finalSignveri = Convert.FromBase64String(finalsignature); 
     bool verified = digitalSignature.VerifySignature(hashedDocument, finalSignveri); 

und die digitale Signatur Klasse ist wie folgt:

public class DigitalSignature 
{ 
    private RSAParameters publicKey; 
    private RSAParameters privateKey; 

    public void AssignNewKey() 
    { 
     using (var rsa = new RSACryptoServiceProvider()) 
     { 
      rsa.PersistKeyInCsp = false; 
      publicKey = rsa.ExportParameters(false); 
      privateKey = rsa.ExportParameters(true); 
     } 
    } 

    public byte[] SignData(byte[] hashOfDataToSign) 
    { 
     using (var rsa = new RSACryptoServiceProvider()) 
     { 
      rsa.PersistKeyInCsp = false; 
      rsa.ImportParameters(privateKey); 

      var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa); 
      rsaFormatter.SetHashAlgorithm("SHA1"); 

      return rsaFormatter.CreateSignature(hashOfDataToSign); 
     } 
    } 

    public bool VerifySignature(byte[] hashOfDataToSign, byte[] signature) 
    { 
     using (var rsa = new RSACryptoServiceProvider()) 
     { 
      rsa.ImportParameters(publicKey); 

      var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa); 
      rsaDeformatter.SetHashAlgorithm("SHA1"); 

      return rsaDeformatter.VerifySignature(hashOfDataToSign, signature); 
     } 
    } 
} 

Könnten Sie mir bitte mitteilen, welche Daten sind speziell für Sie suchen in Wsdl? Leider kann ich die vollständigen WSDL-Informationen hier nicht bereitstellen.

Der Fehler zurückgegeben wird, ich glaube Benutzer behandelt und Zustände „Digitale Signaturprüfung Fehler“

[Redited]

Bitte unter einem Ausschnitt aus dem Code finden, der in Java digitale Signatur erzeugt. Dies wurde von der dritten Partei als Referenz gesendet. Ich bin kein Java-Entwickler. Könnte mich jemand wissen lassen, ob der C# -Code, den ich geschrieben habe, dem Java-Code entspricht? Wenn nicht, lass es mich wissen, wo ich falsch liege.

private static String createDigitalSignature(Key key, byte[] data) { 

    byte[] signature = null; 

    try { 
     // Initialize xml-security library 
     org.apache.xml.security.Init.init(); 

     // Build DOM document from XML data 
     DocumentBuilderFactory dfactory = DocumentBuilderFactory 
       .newInstance(); 
     dfactory.setNamespaceAware(true); 
     dfactory.setValidating(true); 
     DocumentBuilder documentBuilder = dfactory.newDocumentBuilder(); 
     // This is to throw away all validation errors 
     documentBuilder 
       .setErrorHandler(new org.apache.xml.security.utils.IgnoreAllErrorHandler()); 
     Document doc = documentBuilder 
       .parse(new ByteArrayInputStream(data)); 

     // Build canonicalized XML from document 
     Canonicalizer c14n = Canonicalizer 
       .getInstance("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"); 
     byte[] canonBytes = c14n.canonicalizeSubtree(doc); 

     // Initialize signing object with SHA1 digest and RSA encryption 
     Signature rsa = Signature.getInstance("SHA1withRSA"); 

     // Set private key into signing object 
     rsa.initSign((PrivateKey) key); 

     // Generate signature 
     rsa.update(canonBytes); 
     signature = rsa.sign(); 
    } catch (Exception ex) { 
     System.out.println("Exception occurred in createDigitalSignature: " 
       + ex.toString()); 
     System.exit(-1); 
    } 

    // Base64 encode signature 
    BASE64Encoder b64e = new BASE64Encoder(); 
    String signatureString = b64e.encode(signature); 

    return signatureString; 
} 
+0

können Sie den Fehler es verwenden, müssen Sie zurück? Wir brauchen mehr Informationen. Wie sieht die WSDL aus? Wie lang ist deine Signatur? – lumee

Antwort

0

In Schritt 3 ist eine digitale Signatur nicht genau das gleiche wie ein Digest verschlüsseln. Eine digitale RSA-Signatur mit dem Format pkcs#1 verkettet die DigestAlgorithm-OID (den Bezeichner) mit dem Digest-Wert. Sie erzeugen also eine ungültige Signatur.

Alle Programmiersprachen verfügen über eine Methode, um digitale Signaturen ohne Digests und Verschlüsselungen auszuführen. Ich bin kein # Programmierer C, aber ich denke, man RSACryptoServiceProvider.SignData

Verwendung auch VerifyData zur Überprüfung der Signatur

+0

Vielen Dank für Ihre Antwort. Ich habe den Beitrag neu redigiert. Ich habe einen anderen Weg ausprobiert, um die Signatur zu erstellen. Ich habe die Verifizierungsmethode verwendet und sie ist wahr geworden. Aber es schlägt immer noch vom Webservice aus. –

+0

Sie haben zweimal Hashing. Die RSA-Signatur führt auch einen Hash aus. Es sollte "byte [] signature = digitalSignature.SignData (document);' und 'bool verified = digitalSignature.VerifySignature (Dokument, Signatur) sein;' – pedrofb

+0

I modifed it. Aber es gab einen Fehler, der schlechten Hash an der Zeile in der DigitalSignature-Klasse sagt.rsaFormatter.CreateSignature (hashOfDataToSign); –