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/
精彩评论