2011-04-24 115 views
4

我已經在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> 

+1

我沒有研究過這太簽名JSON(RFC 7515),但http://www.bouncycastle.org/java.html API可以幫助 – 2011-04-24 07:16:39

+1

我認爲它不包含在Android SDK中:-( – Waypoint 2011-04-24 07:26:26

+2

不,但它是第三方Java庫,你應該可以使用你的應用程序 – 2011-04-24 07:28:50

回答

3

在J2EE中的Java,你會用javax.xml.crypto這裏詳述

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

但是,這些不是標準Android軟件包的一部分。

可能是一個可管理的數量的工作,使您自己的包你需要的源位。

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

+0

是的,當我意識到XML簽名不存在於J2EE中時,我驚呆了...並且您沒有看到任何其他方式嗎? – Waypoint 2011-04-24 07:06:45

+0

第二個鏈接被打破 – Ika 2014-07-20 08:39:29

1

也許你可以使用Apache的聖所。 http://santuario.apache.org/

+0

當前(1.4 .4)santuario的版本是5.5MB,如果是這樣的話你打算把它包含在android應用程序中。 – peceps 2011-05-11 14:12:02

2

您可以用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轉換到