In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article will explain in detail how the JSR105-based XML signature of JavaSE 6 is realized, and the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
Let's start by analyzing a real example XML signature application.
Cryptographic keys and certificates
We are now ready for our XML signing sample application.
Let's first analyze the following XML document -. / etc/invoice.xml:
XML version= "1.0" encoding= "UTF-8" standalone= "no"? >
< invoice XMLns= "http://www.company.com/accounting" >
< items >
< item >
< desc > Applied Cryptography < / desc >
< type > book < / type >
< unitprice > 44.50 < / unitprice >
< quantity > 1 < / quantity >
< / item >
< / items >
< creditcard >
< number > 123456789 < / number >
< expiry > 10 expiry 20 shock 2009 < / expiry >
< lastname > John < / lastname >
< firstname > Smith < / firstname >
< / creditcard >
< / invoice >
We plan to sign it with an XML signature and want to use a signature method based on a public key.
Let our husband become a cryptographic key. To do this, we can use the keytool tool provided in JDK-move the program to the. / etc folder and execute the following command:
Keytool-genkey-keysize 512-sigalg DSA-dname "cn=Young Yang, ou=Architecture, o=Company, L=New York, ST=NY, c=US"-alias biz-keypass kp1234-keystore bizkeystore-storepass sp1234-validity 180
This command creates the key and pre-stores it with the name bizkeystore, stored in the working directory. / etc, and specifies its password as sp1234. It also generates a public / private key pair for the entity (which contains a prominent name-Young Yang). [note] here the DSA key generation algorithm is used to create public / private keys-both 512 bits long.
The above command further creates a self-signed certificate, which is implemented using SHA1's DSA algorithm (DSA_SHA1 in the JSR-105 comment, which includes the public key and the previous distinguished name information). This certificate will remain valid for 180 days and will be associated with a private key in a key store file (alias "biz" referenced here). The private key is given the password kp1234.
Our example includes a simple Java class, KeyStoreInfo, for outputting the key and certificate information stored in the previous KeyStore file to System.out;, which is also used by the application to obtain key pairs-where private and public key matches are specified as input parameters. To test its ability to output the information contained in the previous storage file bizkeystore, the reader can run the Ant target ksInfo.
The following code snippet shows the method used to retrieve a KeyPair in KeyStoreInfo:
Public static KeyPair getKeyPair (String store,String sPass,String kPass,String alias)
Throws CertificateException
IOException
UnrecoverableKeyException
KeyStoreException
NoSuchAlgorithmException {
KeyStore ks = loadKeyStore (store,sPass)
KeyPair keyPair = null
Key key = null
PublicKey publicKey = null
PrivateKey privateKey = null
If (ks.containsAlias (alias)) {
Key = ks.getKey (alias,kPass.toCharArray ())
If (key instanceof PrivateKey) {
Certificate cert = ks.getCertificate (alias)
PublicKey = cert.getPublicKey ()
PrivateKey = (PrivateKey) key
Return new KeyPair (publicKey,privateKey)
} else {
Return null
}
} else {
Return null
}
}
With a KeyPair, we can easily get PrivateKey and PublicKey- implemented by calling the corresponding operations getPrivate () and getPublic ().
In order to get a PublicKey from KeyStore, we don't really need the key password required in the above method, which is exactly what the following methods do:
Public static PublicKey getPublicKey (String store
String sPass, String alias)
Throws KeyStoreException
NoSuchAlgorithmException
CertificateException
IOException {
KeyStore ks = loadKeyStore (store, sPass)
Certificate cert = ks.getCertificate (alias)
Return cert.getPublicKey ()
}
In the above two code snippets, the method KeyStore loadKeyStore (String store,String sPass) is a utility function that instantiates a KeyStore object and loads the entry from the file system. We implement it in the following ways:
Private static KeyStore loadKeyStore (String store, String sPass)
Throws KeyStoreException
NoSuchAlgorithmException
CertificateException
IOException {
KeyStore myKS = KeyStore.getInstance ("JKS")
FileInputStream fis = new FileInputStream (store)
MyKS.load (fis,sPass.toCharArray ())
Fis.close ()
Return myKS
}
The keytool provided with JDK can also output certificates stored in a key store file to a system file. For example, to create a biz.cer file that contains an X509 certificate associated with a key entry alias biz, we can run the following command from the folder. / etcdirectory:
Keytool-export-alias biz-file biz.cer-keystore bizkeystore-storepass sp1234
This certificate implements authentication we discuss the public key above.
We also include a Java class, CertificateInfo, in the example to output some interesting information from a certificate to System.out. To test this, the reader can run the Ant target certInfo. However, to understand this code and its output, you must have a basic knowledge of DSA and RSA algorithms. Of course, readers can safely bypass this program and continue to read the rest of this article.
Second, the section of generating an Enveloping signature discusses the implementation of signing invoice.xml files with the help of JSR-105 API and its default implementation.
An enveloping signature is created in our example. Note that when you want to use it in a detached or enveloped signature situation, you only need to make some minor changes to this example.
Next, let's analyze the program Sign.java, which can generate the XML signature of the invoice.xml file.
Public class Sign {
Public static void main (String [] args) throws Exception {
String input = ". / etc/invoice.xml"
String output = ". / etc/signature.xml"
If (args.length > 2) {
Input = args [0]
Output = args [1]
}
/ / prepare
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ()
Dbf.setNamespaceAware (true)
/ / step 1
String providerName = System.getProperty ("jsr105Provider", "org.jcp.XML.dsig.internal.dom.XMLDSigRI")
XMLSignatureFactory fac = XMLSignatureFactory.getInstance ("DOM", (Provider) Class.forName (providerName) .newInstance ())
/ / step 2
Reference ref = fac.newReference ("# invoice", fac.newDigestMethod (DigestMethod.SHA1, null))
/ / step 3
Document XML = dbf.newDocumentBuilder () .parse (new File (input))
Node invoice = XML.getDocumentElement ()
XMLStructure content = new DOMStructure (invoice)
XMLObject obj = fac.newXMLObject (Collections.singletonList (content), "invoice", null, null)
/ / step 4
SignedInfo si = fac.newSignedInfo (fac.newCanonicalizationMethod (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS)
(C14NMethodParameterSpec) null)
Fac.newSignatureMethod (SignatureMethod.DSA_SHA1, null)
Collections.singletonList (ref))
/ / step 5, divided into case 5.0 or 5.1
PrivateKey privateKey = null
/ / scenario 5.0
PrivateKey = KeyStoreInfo.getPrivateKey (". / etc/bizkeystore", "sp1234", "kp1234", "biz")
/ / scenario 5.1, divided into case 5.1.1 or 5.1.2
/ / scenario 5.1.1
/ / KeyPairGenerator kpg = KeyPairGenerator.getInstance ("DSA")
/ / kpg.initialize
/ / KeyPair kp = kpg.generateKeyPair ()
/ / scenario 5.1.2
/ / KeyPair kp = KeyStoreInfo.getKeyPair (". / etc/bizkeystore", "sp1234"
/ / "kp1234", "biz")
/ / for scenario 5.1, please remove the comments from the following line
/ / privateKey = kp.getPrivate ()
/ / step 6, divided into situations 6.0, 6.1 or 6.2
/ / scenario 6.0, if the following line is also used for scenario 6.1 or 6.2
KeyInfo ki = null
/ / for case 6.1 or 6.2, please remove the comments from the following line
/ / KeyInfoFactory kif = fac.getKeyInfoFactory ()
/ / scenario 6.1
/ / KeyValue kv = kif.newKeyValue (kp.getPublic ())
/ / ki = kif.newKeyInfo (Collections.singletonList (kv))
/ / scenario 6.2
/ / CertificateFactory cf = CertificateFactory.getInstance ("X.509")
/ / FileInputStream fis = new FileInputStream (". / etc/biz.cer")
/ / java.security.cert.Certificate cert = cf.generateCertificate (fis)
/ / fis.close ()
/ / X509Data x509d = kif.newX509Data (Collections.singletonList (cert))
/ / ki = kif.newKeyInfo (Collections.singletonList (x509d))
/ / step 7
XMLSignature signature = fac.newXMLSignature (si, ki,Collections.singletonList (obj), null, null)
/ / step 8
Document doc = dbf.newDocumentBuilder () .newDocument ()
DOMSignContext dsc = new DOMSignContext (privateKey, doc)
/ / step 9
Signature.sign (dsc)
/ / convert to an xml document
TransformerFactory tf = TransformerFactory.newInstance ()
Transformer trans = tf.newTransformer ()
Trans.transform (new DOMSource (doc), new StreamResult (new FileOutputStream (output)
}
}
To experiment with this program, the reader can run the Ant target signature-it will create an XML document. / etc/signature.xml. This is called a XML signature. To keep our code cleaner and focused, we omitted all relevant formatting in the parsing XML and transforming the DOM tree. As a result, the signature.xml file becomes a somewhat messy text file.
Now, let's take a closer look at this program to show how to sign a XML signature in JSR-105.
The process of signing invoice.xm can be broken down into the following nine steps.
[step 1] load an instance of XMLSignatureFactory. This factory class will be responsible for building almost all the major objects that we need to use when dealing with XML signatures in API in JSR-105, except for those related to KeyInfo.
[step 2] Select a digest method and create the corresponding Reference object. We use the XMLSignatureFactory instance created in [step 1] to create DigestMethod and Reference objects.
The factory operation for the DigestMethod object in XMLSignatureFactory is as follows:
Public abstract DigestMethod newDigestMethod (String algorithm
DigestMethodParameterSpec params) throws NoSuchAlgorithmException
InvalidAlgorithmParameterException
[note] this params parameter is used to specify the parameters that the digest algorithm might need; in the case of SHA-1,SHA-256 or SHA-512, we can use null.
To create a Reference object, XMLSignatureFactory provides four operations:
Public abstract Reference newReference (String uri, DigestMethod dm)
Public abstract Reference newReference (String uri, DigestMethod dm
List transforms, String type, String id)
Public abstract Reference newReference (String uri, DigestMethod dm
List transforms, String type, String id, byte [] digestValue)
.
To fully understand the meaning of the input parameters in those operations, we need to analyze the XML schema definition of the Reference element in the W3C recommendation:
< element name= "Reference" type= "ds:ReferenceType" / >
< complexType name= "ReferenceType" >
< sequence >
< element ref= "ds:Transforms" minOccurs= "0" / >
< element ref= "ds:DigestMethod" / >
< element ref= "ds:DigestValue" / >
< / sequence >
< attribute name= "Id" type= "ID" use= "optional" / >
< attribute name= "URI" type= "anyURI" use= "optional" / >
< attribute name= "Type" type= "anyURI" use= "optional" / >
< / complexType >
Where the URI attribute refers to the corresponding data object of the Reference.
For our example, we use SHA-1 as the digest method and # invoice to reference an element in the same XML-signed document that contains the XML description of the Reference object. The element referenced by # invoice is exactly what we will discuss in the next step.
[@ more@] [step 3] load invoice.xml and wrap it with a XMLObject object. Note that not all signature generation processes require this step. XMLObject models the optional Object elements that we discussed briefly earlier in JSR-105. The Object element has the following schema definition:
< element name= "Object" type= "ds:ObjectType" / >
< complexType name= "ObjectType" mixed= "true" >
< sequence minOccurs= "0" maxOccurs= "unbounded" >
< any namespace= "# # any" processContents= "lax" / >
< / sequence >
< attribute name= "Id" type= "ID" use= "optional" / >
< attribute name= "MimeType" type= "string" use= "optional" / >
< attribute name= "Encoding" type= "anyURI" use= "optional" / >
< / complexType >
XMLSignatureFactory provides the following methods to create an instance of XMLObject:
Public abstract XMLObject newXMLObject (List content, String id,String mimeType,String encoding)
We use a DOMStructure object to wrap the root node of invoice.xml. The DOMStructure defined in JSR-105 helps import nodes into the JSR-105 runtime from the original XML document to be signed.
We specify # invoice as the id of the result object element. The JSR-105 implementation knows that the reference object created in step 2 refers to the invoice.xml document because the id links them together (on the Reference side, the URI attribute points to the id).
[step 4] create a SignedInfo object. In the W3C recommendation, the SignedInfo element has the following schema definitions:
< element name= "SignedInfo" type= "ds:SignedInfoType" / >
< complexType name= "SignedInfoType" >
< sequence >
< element ref= "ds:CanonicalizationMethod" / >
< element ref= "ds:SignatureMethod" / >
< element ref= "ds:Reference" maxOccurs= "unbounded" / >
< / sequence >
< attribute name= "Id" type= "ID" use= "optional" / >
< / complexType >
To create a SignedInfo object, we need two more instances of Reference; that we created in [step 2]-one is an instance of CanonicalizationMethod and the other is an instance of SignatureMethod. We suggest that interested readers refer to the specification specification to get a more accurate understanding of the four XML specification algorithms; here, we simply point out that after we decide to choose a specific algorithm-alg, a subsequent call to an instance of XMLSignatureFactory (that is, fac) will create an instance of CanonicalizationMethod:
Fac.newCanonicalizationMethod (alg,null)
We can create an instance of SignatureMethod-by calling the following actions defined in XMLSigantureFactory:
Public abstract SignatureMethod newSignatureMethod (String algorithm
SignatureMethodParameterSpec params) throws NoSuchAlgorithmException
InvalidAlgorithmParameterException
In our example, we have a key pair of type DSA; therefore, we need to choose an DSA-based algorithm-for example, DSA_SHA1. For DSA-SHA1, we can set the params parameter to null.
To create an instance of SignedInfo, XMLSignatureFactory defines the following two factory methods:
Public abstract SignedInfo newSignedInfo (CanonicalizationMethod cm
SignatureMethod sm, List references)
Public abstract SignedInfo newSignedInfo (CanonicalizationMethod cm
SignatureMethod sm, List references, String id).
The second parameter in the second factory method, id, responds to the Id attribute of the SignedInfo element in the XML signature document.
[step 5]-get the signed private key.
In our example, we show three different ways to get the private key. In the first method, we call the getPrivateKey () method of our KeyStoreInfo class to retrieve the DSA type private key we created using keytool and store it in the key store file-bizkeystore (in the previous 5.0case). To obtain the private key, we can also retrieve the KeyPair- from bizkeystore by calling the getKeyPair () method of KeyStoreInfo, and then calling getPrivate () of the KeyPair instance (5.1.2 case). On the other hand, JCA provides a class named KeyPairGenerator to dynamically create a KeyPair at any time as needed, which is the case mentioned in case 5.1.1 in Sign.java.
Readers should also note that JSR-105 allows private keys to be obtained through a KeySelector object. We will analyze it in more detail when we discuss KeySelector in the next section.
[step 6] create a KeyInfo object. This step is optional, just as KeyInfo is optional as one of the signature elements. In our example case 6. 0, we make KeyInfo a null; so that it can be completely ignored from the resulting XML signature.
The W3C recommends and JSR-105 to define the KeyValues of RSA and the DSA type for wrapping,respectively,RSA and DSA public keys and allow them to become the content of KeyInfo. Scenario 6.1 in our example creates a KeyValue object from the public key we previously generated using JDK keytool and places it in a KeyInfo object. Later, when we discuss our core verifier, we will see how it uses such a KeyInfo object to retrieve the public key for signature verification.
In JSR-105, we create KeyValue and KeyInfo objects by invoking an operation in an KeyInfoFactory instance. Where KeyInfoFactory is responsible for creating all the major KeyInfo-related objects-such as KeyName,KeyValue,X509Data, and so on. We can get an XMLSignatureFactory instance in the same way that we got the KeyInfoFactory instance in step 1. Our example calls the getKeyInfoFactory () method of the XMLSignatureFactory object to get the KeyInfoFactory instance.
Scenario 6.2 of our example will create a X509Data object-using the certificate biz.cer that we previously exported from bizkeystore with the help of the tool keytool, and then put this object as content in a KeyInfo object. Third, the core verifier we will discuss later will demonstrate how we can obtain a public key for signature verification from such a KeyInfo object.
[step 7] create a XMLSignature object. In JSR-105, the XMLSignature interface models the signature elements recommended in the W3C. We have seen the structure of the signature element earlier. To create an instance of XMLSiganture, we can call one of the following two methods in XMLSignatureFactory:
Public abstract XMLSignature newXMLSignature (SignedInfo si, KeyInfo ki)
Public abstract XMLSignature newXMLSignature (SignedInfo si, KeyInfo ki
List objects, String id, String signatureValueId).
The id and signatureValueId parameters in the second method will become the XML element ID in the resulting XML signature document. In our example, the XML signature will have an Object element; therefore, we need to use the second factory method.
[step 8] instantiate a DOMSignContext object and use it to register the private key. The XMLSignContext interface (which DOMSignContext implements) contains the context information signature used to generate the XML.
DOMSignContext provides several forms of constructors-signing applications for registering private keys to use, and this is the approach used in our example.
Before moving on to the final steps of the signing process, we need to point out that both XMLSignContext and DOMSignContext instances may contain information and status specific to the XML signature structure they use. The JSR-105 specification states that if a XMLSignContext (or DOMSignContext) is used with different signature structures, the results will be unpredictable. For example, we should not use the same XMLSignContext (or DOMSignContext) instance to sign two different XMLSignature objects.
[step 9] sign. The sign () operation in the XMLSignature interface implements the signature XMLSignature. In fact, this method also implements several operations, including calculating the digest values of all references based on the corresponding digest method, and calculating the signature value based on the signature method and the private key. The signature value is captured by the embedded SignatureValue class in the XMLSignature instance, and the call to the getSignatureValue () method of the XMLSignature instance returns the SignatureValue object populated with the result value.
At the end of our signature program, we orchestrated the XMLSignature into an XML document-signature.xml.
Third, XML signature Core Verification in the previous section, we signed the invoice.xml document into an enveloping XML signature captured in the signature.xml file.
To verify the signature, we can use the following program-Validate.java:
Public class Validate {
Public static void main (String [] args) throws Exception {
/ / the first step
String providerName = System.getProperty ("jsr105Provider", "org.jcp.XML.dsig.internal.dom.XMLDSigRI")
XMLSignatureFactory fac = XMLSignatureFactory.getInstance ("DOM", (Provider) Class.forName (providerName) .newInstance ())
/ / step 2
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ()
Dbf.setNamespaceAware (true)
Document doc = dbf.newDocumentBuilder () .parse (new FileInputStream (args [0]))
/ / step 3
NodeList nl = doc.getElementsByTagNameNS (XMLSignature.xmlNS, "Signature")
If (nl.getLength () = = 0) {
Throw new Exception ("Cannot find Signature element!")
}
/ / step 4, divided into situation 4.0, 4.1, 4.2 or 4.3.
/ / case 4.0
DOMValidateContext valContext = new DOMValidateContext (new KeyStoreKeySelector (), nl.item (0))
/ / scenario 4.1, scenario 6.1 in Sign.java is required
/ / DOMValidateContext valContext = new DOMValidateContext (
/ / new KeyValueKeySelector (), nl.item (0))
/ / scenario 4.2, scenario 6.2 in Sign.java is required
/ / KeyStore ks = KeyStore.getInstance ("JKS")
/ / FileInputStream fis = new FileInputStream (". / etc/bizkeystore")
/ / ks.load (fis, "sp1234" .toCharArray ())
/ / fis.close ()
/ / X509KeySelector x509ks = new X509KeySelector (ks)
/ / DOMValidateContext valContext = new DOMValidateContext (x509ks, nl.item (0))
/ / situation in 4.3
/ / PublicKey pKey = KeyStoreInfo.getPublicKey (". / etc/bizkeystore"
/ / "sp1234", "biz")
/ / step 5
XMLSignature signature = fac.unmarshalXMLSignature (valContext)
/ / XMLSignature signature = fac.unmarshalXMLSignature (new DOMStructure (nl.item (0)
/ / step 6
Boolean coreValidity = signature.validate (valContext)
/ / check the core verification status
If (coreValidity = = false) {
System.err.println ("Signature failed core validation!")
Boolean sv = signature.getSignatureValue () .validate (valContext)
System.out.println ("Signature validation status:" + sv)
/ / check and check status of each Reference
Iterator I = signature.getSignedInfo (). GetReferences (). Iterator ()
For (int j = 0; i.hasNext (); jacks +) {
Boolean refValid = ((Reference) i.next ()) .validate (valContext)
System.out.println ("Reference (" + j + ") validation status:" + refValid)
}
} else {
System.out.println ("Signature passed core validation!")
}
}
}
To test this program, the reader can run the Ant target check. The program prints the core check status to System.out. If the signature is valid, "Signature passed core validation!" will be output; otherwise, the verification status of the reference and signature will be shown in the output; thus, we can figure out exactly which of them caused the failure.
The process of verifying signature.xml can be broken down into six steps.
Step 1-load an instance of XMLSignatureFactory, which is the same as in the signing program.
Step 2-load the XML signature to be verified. In this step, we need to load the XML containing the XML signature into memory and convert the XML document into a DOM tree.
Step 3-identify the signature node in the DOM tree. The signature is defined in the namespace http://www.w3.org/2000/09/XMLdsig# and is described as the static variable XMLNS of the XMLSignature interface in JSR-105.
Step 4-create an instance of DOMValidateContext.
One of the most critical pieces of information in a validation context is obviously the key. We can use DOMValidateContext and register the public key in two different ways. In the first method, if the verification application already has a public key, it can put the key directly into the context through the constructor of the following DOMValidateContext:
Public DOMValidateContext (Key validatingKey,Node node)
This is the case 4.3 in our example.
The second method registers a KeySelector with DOMValidateContext and lets the KeySelector select the public key-based on the information available in the XMLSignature object to be verified. In JSR-105, KeySelector is an abstract class that defines two operations:
Public abstract KeySelectorResult select (KeyInfo keyInfo, Purpose purpose
AlgorithmMethod method, XMLCryptoContext context)
Throws KeySelectorException
Public static KeySelector singletonKeySelector (Key key)
The second operation creates a KeySelector that always returns the same key. The first operation attempts to select a key-which meets the requirements for passing as output.
KeySelectorResult is an interface in JSR-105-the specification requires that this interface contain a key value selected using KeySelector. In our example, we use the SimpleKeySelectorResult class to implement this interface-simply wrapping the selected public key.
In our example, we implement and utilize three different KeySelectors to illustrate some of the situations in which a validation application works.
In case 4. 0, KeyStoreKeySelector retrieves the public key from a Key store based on input parameters.
In case 4.1, KeyValueKeySelector selects a key based on the KeyValue information in the input KeyInfo object (which should contain a KeyValue object as part of its content; refer to case 6.1 in Sign.java).
In case 4.2, X509KeySelector selects a key based on the X509Data and other information contained in the KeyInfo object (which should contain a X509Data object as part of its content; refer to case 6.2 in Sign.java). We are using X509KeySelector in JSR-105-whose original author is Sean Mullan. Here, we modify the private certSelect () method slightly so that it is suitable for our certificate generated by keytool.
Since the KeyInfo in the signature may contain all kinds of information, it is clear that an application must choose an KeySelector implementation-it uses the information contained in the KeyInfos it will process.
Step 5-unorchestrate the signature node into a XMLSiganture object. In the previous step, we loaded the signature.xml file into a DOM tree-identified by the node corresponding to the Signature element in the tree, and registered the node with a DOMValidateContext and KeySelector (or private key). To verify the XML signature, we need to unorchestrate the Signature node into a XMLSignature object. This is achieved by calling the following XMLSignatureFactory operation:
Public abstract XMLSignature unmarshalXMLSignature (XMLValidateContext context)
Throws MarshalException
Step 6-verify the XML signature. This is achieved by calling the validate () method of the XMLSignature instance-with DOMValidateContext as the only input parameter.
The validate () method verifies the XML signature according to the core verification process defined in the W3C recommendation. As mentioned earlier, this process consists of two parts. One is to verify all references. In JSR-105, this can be done by calling the validate () operation of the Reference interface-with the relevant validation context as the input parameter.
The second part of this core check is signature verification-the signature value of the SignedInfo element of the verification specification. With the help of JSR-105, we can do this explicitly-by calling the validate () method of the SignatureValue object associated with the XMLSignature instance, with the relevant validation context as the input parameter.
In our example, we use this knowledge to output the verification status of each Reference and SigantureValue-when the XML signature (core) verification fails; thus, we can get more detailed information that caused the failure.
4. Modify XML signature to show that the verifier can indeed capture changes to the generated XML signature, we can create a Tamper.java program in our example that allows us to modify the credit card number in the list (or the SignatureValue element in the signature.xml file).
This program uses an XML signature document and a Boolean value as parameters. When the Boolean parameter is true, the program changes the credit card number; otherwise, it modifies the signature value.
Public class Tamper {
Public static void main (String [] args) throws Exception {
String sigfile = "etc/signature.xml"
/ / decide which flag to modify-Reference or SignatureValue
Boolean tamperRef = true
If (args.length > = 2) {
Sigfile = args [0]
TamperRef = Boolean.parseBoolean (args [1])
}
File file = new File (sigfile)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ()
Dbf.setNamespaceAware (true)
Document signature = dbf.newDocumentBuilder () .parse (file)
If (tamperRef) {
/ / modify the credit card number
NodeList targets = signature.getDocumentElement () .getElementsByTagName ("number")
Node number = targets.item (0)
If (! number.getTextContent () .equals ("987654321")) {
Number.setTextContent ("987654321")
} else {
Number.setTextContent ("000000000")
}
} else {
/ / modify SignatureValue (first byte)
BASE64Encoder en = new BASE64Encoder ()
BASE64Decoder de = new BASE64Decoder ()
NodeList sigValues = signature.getDocumentElement () .getElementsByTagName ("SignatureValue")
Node sigValue = sigValues.item (0)
Byte [] oldValue = de.decodeBuffer (sigValue.getTextContent ())
If (oldValue [0]! = 111) {
OldValue [0] = (byte) 111
} else {
OldValue [0] = (byte) 112
}
SigValue.setTextContent (en.encode (oldValue))
}
TransformerFactory tf = TransformerFactory.newInstance ()
Transformer trans = tf.newTransformer ()
Trans.transform (new DOMSource (signature), new StreamResult (new FileOutputStream (file)
}
}
To run it, the reader can execute the modified Ant target. After running the modified program, if we run the verifier again, the core verification will fail, and System.out will output the status of the reference and signature verification, respectively. Depending on the value of the second Boolean input parameter, reference and / or signature verification may report a failure.
On JavaSE 6 JSR105-based XML signature is how to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.