xml signature
27518 ワード
デジタル署名は、金融チャネルで働くときにある銀行が使用するW 3 Cのxml signatureを説明します.使用にはいくつかの難易度があり、通常のRSAとチェックマークを使用するよりも、w 3 c xml signatureには既存のオープンソースコードがありますが、jdkが持参したものを使用することをお勧めしません.jdkバージョンの互換性がないとだめです.署名仕様はXML-Signature Syntax and Processing,W 3 C Recommendation仕様(http://www.w3.org/TR/xmldsig-core/). Financeプロトコルは、分離署名(Detached signature)を使用します.すなわち、要素と署名された要素(例えば、CSReq/SResなど)はそれぞれ独立して存在します.署名された要素と要素は同じドキュメントに含まれます.署名要素は、'#CSReq 1234'などのローカル参照によって参照される.署名された要素の内容は、CSReq/SRes等の開始ラベルの開始括弧からCSReq/SRes等の終了ラベルの終了括弧までの内容を含む.署名構造図署名要求要素はSignatureにKeyInfoインスタンスがないことを要求する.ObjectインスタンスCanonicalizationMethod要素は空ではありませんが、Algorithm属性SignatureMethod要素は空ですが、Algorithm属性Transformsが存在し、いずれも1つのTransformを含むインスタンスTransform要素は空ですが、Algorithm属性DigestMethod要素は空ですが、Algorithm属性KeyInfoは表示されません.Canonicalization http://www.w3.org/TR/2001/REC-xml-cl4n-20010315 Digest http://www.w3.org/2000/09/xmldsig#shal Encoding http://www.w3.org/2000/09/xmldsig#base64 Signature http://www.w3.org/2000/09/xmldsig#rsa-sha1 Transform http://www.w3.org/2000/09/xmldsig#enveloped-signature
署名ネーミングスペースメッセージの署名は、デフォルトのネーミングスペースに宣言する必要があります.http://www.w3.org/2000/09/xmldsig#に表示されます.
署名例
コード実装jarパッケージは、sun jdkが持参したものを推奨せず、IBMjdk環境ではxmlsec xercesImplをコンパイルできない コード1 OfflineResolver コード2、署名、チェック
署名ネーミングスペースメッセージの署名は、デフォルトのネーミングスペースに宣言する必要があります.http://www.w3.org/2000/09/xmldsig#に表示されます.
署名例
< Finance>
<Message id="111">
<CSReq id="CSReq">
<version>1.0.1version>
<date>20070625 11:51:39date>
<instId>WZCBinstId>
<certId>123456certId>
<signNo>200705131234567890signNo>
<cardNo>123456cardNo>
<cardType>DcardType>
<name> name>
<gender>Mgender>
<certType>1certType>
<certNo>111111111111111certNo>
<email>[email protected]email>
<cell>13588888888cell>
<address> address>
<memo> memo>
CSReq>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">
CanonicalizationMethod>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
SignatureMethod>
<Reference URI="#CSReq">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
Transform>
Transforms>
<DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
DigestMethod> <DigestValue>4t79dXZ7/BQqgiBdkziaKTUslVU=DigestValue>
Reference>
SignedInfo> <SignatureValue>RyWMXvxlhmLuOIOvGSIkpV1iRV400F1B2W0zmW9nc5qfvfNMtpyp+uNwksBUjcO8H//NW4GvxcDdKMuuc6k5MDMH1E4OUg+624FUY23qs3R2ztubtD3MU7xk4f0iq9L16GK4ZBeID/Lyj6CxjaCcp3FuK1CznNj4Kr+qRLtxx+s= SignatureValue>
Signature>
Message>
Finance>
コード実装
import org.apache.xerces.util.URI;
import org.apache.xml.security.Init;
import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.utils.resolver.ResourceResolverException;
import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
import org.w3c.dom.Attr;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class OfflineResolver extends ResourceResolverSpi
{
public OfflineResolver()
{
}
public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
throws ResourceResolverException
{
try
{
String URI = uri.getNodeValue();
if(_uriMap.containsKey(URI))
{
String newURI = (String)_uriMap.get(URI);
InputStream is = new FileInputStream(newURI);
XMLSignatureInput result = new XMLSignatureInput(is);
result.setSourceURI(URI);
result.setMIMEType((String)_mimeMap.get(URI));
return result;
} else
{
Object exArgs[] = {
"The URI " + URI + " is not configured for offline work"
};
throw new ResourceResolverException("generic.EmptyMessage", exArgs, uri, BaseURI);
}
}
catch(IOException ex)
{
throw new ResourceResolverException("generic.EmptyMessage", ex, uri, BaseURI);
}
}
public boolean engineCanResolve(Attr uri, String BaseURI)
{
String uriNodeValue = uri.getNodeValue();
if(uriNodeValue.equals("") || uriNodeValue.startsWith("#"))
return false;
try
{
URI uriNew = new URI(new URI(BaseURI), uri.getNodeValue());
if(uriNew.getScheme().equals("http"))
{
return true;
}
}
catch(URI.MalformedURIException malformeduriexception) { }
return false;
}
private static void register(String URI, String filename, String MIME)
{
_uriMap.put(URI, filename);
_mimeMap.put(URI, MIME);
}
static Map _uriMap = null;
static Map _mimeMap = null;
static
{
// TODO : ! , //
Init.init();
_uriMap = new HashMap();
_mimeMap = new HashMap();
register("http://www.w3.org/TR/xml-stylesheet", "data/org/w3c/www/TR/xml-stylesheet.html", "text/html");
register("http://www.w3.org/TR/2000/REC-xml-20001006", "data/org/w3c/www/TR/2000/REC-xml-20001006", "text/xml");
register("http://www.nue.et-inf.uni-siegen.de/index.html", "data/org/apache/xml/security/temp/nuehomepage", "text/html");
register("http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/id2.xml", "data/org/apache/xml/security/temp/id2.xml", "text/xml");
register("http://xmldsig.pothole.com/xml-stylesheet.txt", "data/com/pothole/xmldsig/xml-stylesheet.txt", "text/xml");
register("http://www.w3.org/Signature/2002/04/xml-stylesheet.b64", "data/ie/baltimore/merlin-examples/merlin-xmldsig-twenty-three/xml-stylesheet.b64", "text/plain");
}
}
import org.apache.commons.io.IOUtils;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.signature.XMLSignatureException;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.XMLUtils;
import org.apache.xpath.XPathAPI;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class XmlSignature {
/**
*
* @param document
* @param messageType
* @param privateKey
* @param password
* @return
* @throws Exception
*/
public static String generateXMLDigitalSignature1(Document document, String messageType, PrivateKey privateKey, String password) throws Exception {
ByteArrayOutputStream os = null;
// document W3C
org.w3c.dom.Document doc = parse(document);// DOM4J >>> W3C
XMLSignature sig = new XMLSignature(doc, doc.getDocumentURI(), XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);//
sig.getSignedInfo().addResourceResolver(new OfflineResolver());
Node messageNode = doc.getElementsByTagName("Message").item(0);
messageNode.appendChild(sig.getElement());
Transforms transforms = new Transforms(doc);
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
//
sig.addDocument("#" + messageType, transforms, Constants.ALGO_ID_DIGEST_SHA1);
sig.sign(privateKey);
os = new ByteArrayOutputStream();// XML
XMLUtils.outputDOM((Node) doc, os);
return os.toString("UTF-8");
}
/**
*
* @param signatureXml
* @param publicKeyByte
* @return
* @throws Exception
*/
public static boolean validateXMLDigitalSignature(String signatureXml, byte[] publicKeyByte) throws Exception {
ByteArrayInputStream is = null;
try {
CertificateFactory certificatefactory;
certificatefactory = CertificateFactory.getInstance("X.509");
//
is = new ByteArrayInputStream(publicKeyByte);
X509Certificate cert = (X509Certificate) certificatefactory.generateCertificate(is);
PublicKey pk = cert.getPublicKey();
org.w3c.dom.Document doc = (org.w3c.dom.Document) parse(DocumentHelper.parseText(signatureXml));
Element nscontext = XMLUtils.createDSctx(doc, "ds", "http://www.w3.org/2000/09/xmldsig#");
Element signElement = (Element) XPathAPI.selectSingleNode(doc, "//ds:Signature[1]", nscontext);
//
if (signElement == null) {
return false;
}
XMLSignature signature;
signature = new XMLSignature(signElement, doc.getDocumentURI());
return signature.checkSignatureValue(pk);
} catch (TransformerException e) {
throw new Exception(" !Exception is : " + e);
} catch (XMLSignatureException e) {
throw new Exception("XML !Exception is : " + e);
} catch (XMLSecurityException e) {
throw new Exception("XML !Exception is :" + e);
} catch (CertificateException e) {
throw new Exception(" !Exception is :" + e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
throw new Exception("XML !Exception is : " + e);
}
}
}
}
public static PrivateKey getPrivateKey(byte[] privateKeyStream, String privateKeyPassword,String keyAlias) throws Exception {
if (privateKeyStream == null) {
throw new RuntimeException("nullPointException: privateKey byte is null");
}
if (privateKeyPassword == null) {
throw new RuntimeException("nullPointException: privateKeyPassword is null");
}
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream inputStream = new ByteArrayInputStream(privateKeyStream);
keyStore.load(inputStream, privateKeyPassword.toCharArray());
PrivateKey p =(PrivateKey) keyStore.getKey(keyAlias, privateKeyPassword.toCharArray());
return p;
}
public static PublicKey getPublicKey(byte[] publicKeyStream) throws Exception {
if (publicKeyStream == null) {
throw new RuntimeException("nullPointException: publicKey byte is null");
}
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream inputStream = new ByteArrayInputStream(publicKeyStream);
Certificate c = cf.generateCertificate(inputStream);
return c.getPublicKey();
}
/**
* dom4j org.w3c.dom.Document
* @param doc
* @return
* @throws
*/
public static org.w3c.dom.Document parse(Document doc) throws Exception{
if (doc == null) {
return (null);
}
InputStream is = null;
try {
is = IOUtils.toInputStream(doc.asXML(), "UTF-8");
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
is.close();
return docBuilder.parse(is);
} catch (IOException e) {
throw new Exception("XML !Exception is : " + e);
} catch (SAXException e) {
throw new Exception(" !Exception is : " + e);
} catch (ParserConfigurationException e) {
throw new Exception(" !Exception is : " + e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
throw new Exception("XML !Exception is : " + e);
}
}
}
}
}