Android - 验证XML的签名
我已经在Web上签名了XML文档(通过纯Java与RSA和X509标签),并且我已经实现了XML拉解析器 - 在我将XML文档中的某些信息解析为特定URL之前,我需要验证这个文件,如果它是正确的。你知道如何检查XML签名吗?Android - 验证XML的签名
感谢
编辑:
我的XML文件看起来像如下:
<?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>
在J2EE中的Java,你会用javax.xml.crypto
这里详述
http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/
但是,这些不是标准Android软件包的一部分。
它可能是一个可管理的数量的工作,使您自己的包你需要的源位。
也许你可以使用Apache的圣所。 http://santuario.apache.org/
当前(1.4 .4)santuario的版本是5.5MB,如果是这样的话你打算把它包含在android应用程序中。 – peceps 2011-05-11 14:12:02
您可以使用Apache Santuario,但需要将其剥离。查看https://web.archive.org/web/20140902223147/http://www.xinotes.net/notes/note/1302/了解更多详情。
有更多关于如何使用它的细节? – dove 2012-11-05 08:38:38
您可以用XML安全功能添加Apache的圣所的下面剥离版本:http://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.0.2
然后你只需要创建一些验证类,例如:
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();
}
}
编辑 似乎比如在Android中包含XML解析库比预期更复杂。首先,您需要生成jar文件,然后修改一些库名称空间(使用JarJar工具)。之后,将其添加到项目的库目录(/ lib或/ libs)中。 Source
我从签名的XML转换到
我没有研究过这太签名JSON(RFC 7515),但http://www.bouncycastle.org/java.html API可以帮助 – 2011-04-24 07:16:39
我认为它不包含在Android SDK中:-( – Waypoint 2011-04-24 07:26:26
不,但它是第三方Java库,你应该可以使用你的应用程序 – 2011-04-24 07:28:50