<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import java.security.*;
import java.security.interfaces.*;
import java.io.*;

/** Computes a digital signature for an XML file */

public class SignXML
{
    public static void main(String[] args)
    {
        try
        {
            String keystorePassword = "changeit";
            String testAlias = "signkey";
            String testKeyPassword = "changeit";

// Create a keystore.
            KeyStore keystore = KeyStore.getInstance("JKS");

// Figure out where the user's keystore is located.
            String keystoreFilename = System.getProperty("user.home")+
                File.separator+".keystore";
                
// Load the keystore from the keystore file.
            keystore.load(new FileInputStream(keystoreFilename),
                keystorePassword.toCharArray());

// Locate the key with the specified alias and password.
            Key testkey = keystore.getKey(testAlias,
                testKeyPassword.toCharArray());

// Assume that the key is an RSA key.
            RSAPrivateKey pvtKey = (RSAPrivateKey) testkey;

// Get the certificate for the key (not for computing the signature,
// just for writing out to a separate file for later signature verification).
            java.security.cert.Certificate cert =
                keystore.getCertificate(testAlias);

// Get the public key from the certificate.
            RSAPublicKey pubKey = (RSAPublicKey) cert.getPublicKey();

// Create and initialize a signer to use MD5 and RSA.
            Signature signer = Signature.getInstance("MD5withRSA");
            signer.initSign(pvtKey);

// Create a message digest, because the XML signature must contain
// the message digest.
            MessageDigest digest = MessageDigest.getInstance("MD5");

// Open the XML file.
            FileInputStream in = new FileInputStream(args[0]);

// Create a block of bytes for reading the file.
            byte[] buffer = new byte[4096];
            int len;

// Read a block of the file and add it to the signature object.
            while ((len = in.read(buffer)) &gt; 0)
            {
                signer.update(buffer, 0, len);
                digest.update(buffer, 0, len);
            }
            in.close();

// Compute the digital signature.
            byte signatureBytes[] = signer.sign();

            byte digestBytes[] = digest.digest();
        
// Write the signature out to a file.
            PrintWriter ps = new PrintWriter(
                new BufferedWriter(
                new FileWriter(args[0]+".sig.xml")));
            
            ps.println("&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;");
            ps.println("&lt;Signature Id=\"SampleSignature\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\"&gt;");
            ps.println("  &lt;SignedInfo&gt;");
            ps.println("    &lt;CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-cl4n-20010315\"/&gt;");
            ps.println("    &lt;Reference URI=\"http://www.w3.org/TR/2000/REC-xhtml1-2000-126/\"&gt;");
            ps.println("      &lt;Transforms&gt;");
            ps.println("        &lt;Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-cl4n-20010315\"/&gt;");
            ps.println("      &lt;/Transforms&gt;");
            ps.println("      &lt;DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#md5\"/&gt;");
            ps.println("      &lt;DigestValue&gt;"+Base64.toBase64(digestBytes)+
                "&lt;/DigestValue&gt;");
            ps.println("    &lt;/Reference&gt;");
            ps.println("  &lt;/SignedInfo&gt;");
            ps.println("  &lt;SignatureValue&gt;");
            ps.println("    "+Base64.toBase64(signatureBytes));
            ps.println("  &lt;/SignatureValue&gt;");
            ps.println("  &lt;KeyInfo&gt;");
            ps.println("    &lt;KeyValue&gt;");
            ps.println("      &lt;RSAKeyValue&gt;");
            ps.println("        &lt;Exponent&gt;");
            ps.println("          "+Base64.toBase64(pubKey.getPublicExponent().toByteArray()));
            ps.println("        &lt;/Exponent&gt;");
            ps.println("        &lt;Modulus&gt;");
            ps.println("          "+Base64.toBase64(pubKey.getModulus().
                toByteArray()));
            ps.println("        &lt;/Modulus&gt;");
            ps.println("      &lt;/RSAKeyValue&gt;");
            ps.println("    &lt;/KeyValue&gt;");
            ps.println("  &lt;/KeyInfo&gt;");
            ps.println("&lt;/Signature&gt;");
            ps.close();
        }
        catch (Exception exc)
        {
            exc.printStackTrace();
        }
    }
}
</pre></body></html>