XML Security项目是为XML安全标准(XML-Signature Syntax and Processing:XML数字签名语法和处理规则;XML Encryption Syntax and Processing:XML加密语法和处理规则)提供Java及C++实现的开源项目。项目主页为:http://santuario.apache.org/index.html
本文给出了一个验证XML文件数字签名的类,使用该类可以方便的对XML文件进行数字签名验证
/************************************************************************/ /* VerifyXMLSig.h */ /************************************************************************/ /** * @file VerifyXMLSig.h * @brief 该类用来验证XML文件的数字签名 * @author wlq_729@163.com * @version 1.0 * @date 2009-02-10 */ #ifndef VERIFYXMLSIG_H_ #define VERIFYXMLSIG_H_ #include <xsec/utils/XSECPlatformUtils.hpp> #include <xsec/framework/XSECProvider.hpp> #include <xsec/canon/XSECC14n20010315.hpp> #include <xsec/dsig/DSIGSignature.hpp> #include <xsec/framework/XSECException.hpp> #include <xsec/enc/XSECCryptoException.hpp> #include <xsec/utils/XSECDOMUtils.hpp> #include <xsec/enc/XSECKeyInfoResolverDefault.hpp> #include <xercesc/util/PlatformUtils.hpp> #include <xercesc/util/XMLString.hpp> #include <xercesc/dom/DOM.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/util/XMLException.hpp> #include <xercesc/util/XMLUri.hpp> #include <memory.h> #include <string.h> #include <iostream> #include <stdlib.h> XERCES_CPP_NAMESPACE_USE using std::cerr; using std::cout; using std::endl; using namespace xercesc; class VerifyXMLSig { public: VerifyXMLSig (); ~VerifyXMLSig (); /* * 初始化XML文件DOM * @param[in] fileName 需要验证的XML文件名 */ int Init(const char* fileName); /* * 验证XML文件的数字签名 */ int CheckSignature(); private: DOMDocument *m_pDOMTree; }; #endif /************************************************************************/ /* VerifyXMLSig.cpp */ /************************************************************************/ #include "VerifyXMLSig.h" VerifyXMLSig::VerifyXMLSig() { // 初始化验证平台 try { XMLPlatformUtils::Initialize(); XSECPlatformUtils::Initialise(); } catch(const XMLException& e) { cerr << "Error during initialisation of Xerces" << endl; cerr << "Error Message = : " << e.getMessage() << endl; } catch (...) { cerr << "Unexpected Xerces or XMLSecurity initialization error." << endl; } } VerifyXMLSig::~VerifyXMLSig() { try { XSECPlatformUtils::Terminate(); XMLPlatformUtils::Terminate(); } catch(XMLException& excp) { cout<<"XML toolkit terminate error:"<<endl; cerr << "Error Message = : "<< excp.getMessage() << endl; } } int VerifyXMLSig::Init(const char* fileName ) { int ret = 0; int errorCount; bool errorsOccured = false; XercesDOMParser * parser = new XercesDOMParser; parser->setDoNamespaces(true); parser->setCreateEntityReferenceNodes(true); try { parser->parse(fileName); errorCount = parser->getErrorCount(); if (errorCount > 0) errorsOccured = true; } catch (const XMLException& e) { cerr << "An error occured during parsing/n Message: " << e.getMessage() << endl; errorsOccured = true; } catch (const DOMException& e) { cerr << "A DOM error occured during parsing/n DOMException code: " << e.code << endl; errorsOccured = true; } if (errorsOccured) { cout << "Errors during parse" << endl; return (-1); } m_pDOMTree = parser->getDocument(); return 0; } int VerifyXMLSig::CheckSignature() { bool result = false; // 获取XML文件Signature字段内容 DOMNode *sigNode = findDSIGNode(m_pDOMTree, "Signature"); // Create the signature checker if (sigNode == 0) { cerr << "Could not find <Signature> node in "<< endl; return (-1); } XSECProvider prov; XSECKeyInfoResolverDefault theKeyInfoResolver; DSIGSignature * sig = prov.newSignatureFromDOM(m_pDOMTree, sigNode); // The only way we can verify is using keys read directly from the KeyInfo list, // so we add a KeyInfoResolverDefault to the Signature. sig->setKeyInfoResolver(&theKeyInfoResolver); try { sig->load(); result = sig->verify(); } catch (XSECException &e) { char * msg = XMLString::transcode(e.getMsg()); cerr << "An error occured during signature verification/n Message: " << msg << endl; XSEC_RELEASE_XMLCH(msg); return (-1); } catch (XSECCryptoException &e) { cerr << "An error occured during signature verification/n Message: " << e.getMsg() << endl; return (-1); } catch (...) { cerr << "Unknown Exception type occured.Cleaning up and exiting/n" << endl; return (-1); } if (result) { return (0); } else { char * e = XMLString::transcode(sig->getErrMsgs()); cout << e << endl; XSEC_RELEASE_XMLCH(e); return (-1); } } /************************************************************************/ /* test.cpp */ /************************************************************************/ #include "VerifyXMLSig.h" void main(void) { VerifyXMLSig verifyXmlSig; verifyXmlSig.Init("test.xml"); int ret; if ((ret = verifyXmlSig.CheckSignature()) == 0) { cout<<"OK!"<<endl; } else { cout<<"Error!"<<endl; } }