开发者

Android - verify the signature of XML

I have signed XML document (by pure Java with RSA and X509 tags) on the web and I have implemented XML pul开发者_高级运维l parser - before I parse some information from my XML document to specific URL, I need to verify this document if it is the right one. Do you know how to check XML signature?

Thanks

edit:

my XML file looks like follows:

 <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
  <application id="1">
  <appversion>1.0</appversion> 
  <obligatory>yes</obligatory> 
  <update>http://www.xyz.....</update> 
  <check>http://www.xyz.....</check> 
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" /> 
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> 
      <ds:Reference URI="#1">
        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> 
        <ds:DigestValue>fuv...</ds:DigestValue> 
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>PC0+4uO4...</ds:SignatureValue> 
  <ds:KeyInfo>
  <ds:KeyValue>
    <ds:RSAKeyValue>
      <ds:Modulus>gEs/Fn2Gd5evwhlUgoS3...</ds:Modulus> 
      <ds:Exponent>AQAB</ds:Exponent> 
    </ds:RSAKeyValue>
  </ds:KeyValue>
  <ds:X509Data>
    <ds:X509IssuerSerial>
      <ds:X509IssuerName>CN=abc abc,OU=abcs,O=abc,L=abc,ST=abc,C=abc</ds:X509IssuerName> 
      <ds:X509SerialNumber>123456...</ds:X509SerialNumber> 
    </ds:X509IssuerSerial>
    <ds:X509SubjectName>CN=abc abc,OU=abcs,O=abc,L=abc,ST=abc,C=abc</ds:X509SubjectName> 
    <ds:X509Certificate>MIIDhzCCAm+gAwIBAgI...</ds:X509Certificate> 
  </ds:X509Data>
  </ds:KeyInfo>
 </ds:Signature>


In J2EE Java you would use javax.xml.crypto as detailed here

http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/

However these are not part of the standard Android package.

It may be a manageable amount of work to make your own package of the bits of the source you need.

http://google.com/codesearch/p?hl=en#-WpwJU0UKqQ/src/share/classes/javax/xml/crypto/dom/DOMCryptoContext.java&d=5


You can use Apache Santuario but you need to strip it down. Look at https://web.archive.org/web/20140902223147/http://www.xinotes.net/notes/note/1302/ for more details.


You can add the following stripped version of Apache Santuario with the XML security features: http://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.0.2

Then you just need to create some verifier class, for example:

import java.io.*;
import javax.xml.parsers.*;
import java.security.PublicKey;
import java.security.cert.X509Certificate;

import org.w3c.dom.*;

import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.XMLUtils;

enter code here

public class Whatever {
    boolean verifySignature() {
    boolean valid = false;
    try {
        // parse the XML
        InputStream in = obtainInputStreamToXMLSomehow();
        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
        f.setNamespaceAware(true);
        Document doc = f.newDocumentBuilder().parse(in);
        in.close();

        // verify signature
        NodeList nodes = doc.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature");
        if (nodes.getLength() == 0) {
        throw new Exception("Signature NOT found!");
        }

        Element sigElement = (Element) nodes.item(0);
        XMLSignature signature = new XMLSignature(sigElement, "");

        KeyInfo ki = signature.getKeyInfo();
        if (ki == null) {
        throw new Exception("Did not find KeyInfo");
        }

        X509Certificate cert = signature.getKeyInfo().getX509Certificate();
        if (cert == null) {
        PublicKey pk = signature.getKeyInfo().getPublicKey();
        if (pk == null) {
            throw new Exception("Did not find Certificate or Public Key");
        }
        valid = signature.checkSignatureValue(pk);
        }
        else {
        valid = signature.checkSignatureValue(cert);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }

    return valid;
    }

    // This is important!
    static {
    org.apache.xml.security.Init.init();
    }
}

Edit Seems like including XML parsing libraries in Android is trickier than expected. First you need to generate the jar file and then modify some of the library namespaces (using JarJar tool). After that, add it to the project's library directory (/lib or /libs). Source

I switched from signed XML to Signed JSON (RFC 7515)


Maybe you can use Apache Santuario. http://santuario.apache.org/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜