CWA2: Proof of concept TOOLS
TOOLS: Signature Creation and Validation
The objective of this document is to explain in short how to use the tools included in the Java Open Source packet signtools.jar to sign and validate signature. Note these tools are part of a proof of concept, and still are in alpha state. These tools are therefore provided “AS IS”, without warranty of any kind.
Note all source codes (batch files, xml, command line, java, etc) end with two lines with three whitespaces an a dot (” .”). This is just only for compatibility with older navigators, and these two lines shouldn’t be considered part of the source code.
Download from here: signtools. Uncompress by example at c:\DEMOS
Before using these tools, you need:
- Java: If Java SE (Standard Edition) is not installed on your computer, download from Oracle and install it. This packet has been tested with java version 1.6.0_45, so this version or a newer one should be fine. If Java SE is installed on your computer, verify version (by using “java –version”), and if needed download and install a newer one.
- Packet signtools_0_3_0.jar. This is the file, developed into the CEN WS XBRL project, where the classes have been packed. These classes are now under development, and are oriented just only as a proof of concept and didactic example, but not to be part of a production system. Source code will be available under an open-source license (EUPL and other FLOSS licenses are being considered).
- A java KeyStore file with public/private RSA keys. You can use the sample java KeyStore file “allJKS.jks” (uncompress this zip file and extract allJKS.jks). This Java KeyStore holds public/private RSA keys. Public keys are in the form of X509 certificates. These certificates are self-generated (issuer=subject), and must be used just only for testing. These are not trusted certificates.
Signature creation: signtools.EnvelopingSignFile
To create a digital signature, use the command:
java -cp signtools_0_3_0.jar signtools.LaunchEnvelopingSignFile -k keystoreFile -p keystorePassword -os keystoreAlias -fts FileNameToSign -f OutputFileName . .
Implementation dependent parameters
- keystoreFile: Is the Java Keystore file (file “allJKS.jks”).
- keystorePassword: Is the password of the Java Keystore File. In the Java KeyStore “allJKS.jks” the password is “XBRL2013” (double quotes excluded).
- Signer. The private key of the signer of the file, others should use signer’s public key for validation. In this implementation, it is a keystoreAlias (Java Keystores identify key pairs by an alias). Current example file “allJKS.jks” store public/private keys for the next aliases:
- FileNameToSign: The file to be embedded in the signature (and signed, using enveloping signature).
- OutputFileName: The xml file to be generated with the signature.
This tool prepares a XML signature structure, read the external file “FileNameToSign” and embed it inside the XML signature structure, in an Object element. This embedded file inside this Object element is coded as Base64, to avoid problems between binary, text and XML files. This Object element has a needed ID attribute, where the filename (FileNameToSign) is stored.
Another Object element is created to hold XADES qualifying properties.
Also, this tool includes the public key and the certificate data (X509Certificate) inside the XML signature structure.
The tool generates the signature using the supplied private key for three XML elements, two XML signature elements “Object” (the file and a sub-element of qualifying properties:, SignedProperties) and the XML signature element “KeyInfo”, with the public key and the data in the X509 certificate. So, the digital signature “protects” these three elements. These three elements are addressed in References: RefFileObject (address the URI of the file object), RefSignedProperties (address the URI of the XAdES SignedProperties) and RefKeyInfo (address the URI of the KeyInfo element, with public key and certificate data). References also holds the name of the digest algorithm (sha512) and the digest value.
The tool finish computing the digital signature, including it in the XML signature structure and saving the output file with this XML signature structure. This signature is computed using the three digest values and the private key, using rsa-sha512.
Sample file (cryptographic and computed values not shown):
<Signature Id="SignatureId"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"/> <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/> <Reference Id="RefFileObject" URI="#file1.zip"> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/> <DigestValue> . . . </DigestValue> </Reference> <Reference Id="RefKeyInfo" URI="#idKeyInfo"> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/> <DigestValue> . . . </DigestValue> </Reference> <Reference Id="RefSignedProperties" Type="http://uri.etsi.org/01903#SignedProperties" URI="#idSignedProperties"> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/> <DigestValue>. . . </DigestValue> </Reference> </SignedInfo> <SignatureValue Id="SignatureValueID"> . . . </SignatureValue> <KeyInfo Id="idKeyInfo"> <KeyValue> <RSAKeyValue> <Modulus> . . . </Modulus> <Exponent> . . . </Exponent> </RSAKeyValue> </KeyValue> <X509Data> <X509Certificate> . . .</X509Certificate> </X509Data> </KeyInfo> <Object Encoding="http://www.w3.org/2000/09/xmldsig#base64" Id="file1.zip" MimeType="application/octet-stream"> . . . </Object> <ds:Object Id="idObject"> <xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Id="QualifyingProperties" Target="#SignatureId"> <xades:SignedProperties id="idSignedProperties"> <xades:SignedSignatureProperties> <xades:SigningTime>2013-10-24T12:51:54</xades:SigningTime> </xades:SignedSignatureProperties> </xades:SignedProperties> </xades:QualifyingProperties> </ds:Object> </Signature> . .
Note: remember to add the appropiate path to every jar file, by example, add c:\demos\cryptools\jars to cryptTools_0_3_0.jar, to commons-logging-1.1.1.jar, etc. Or run the command from the cryptools\jars directory.
Suppose we want to sign file c:\DEMOS\helloworld.txt and store signature and embedeed file in C:\DEMOS\helloworld.signed.xml using java KeyStore file C:\DEMOS\allJKS.jks and alias declarer1:
java -cp signtools_0_3_0.jar signtools.LaunchEnvelopingSignFile -k C:\DEMOS\allJKS.jks -p XBRL2013 -os declarer1 -fts "C:\DEMOS\helloworld.txt" -f C:\DEMOS\helloworld.signed.xml . .
Sample output text on the screen:
17-oct-2013 12:51:54 signtools.SignFile generateDsigEnveloping INFO: Signature created at C:\DEMOS\helloworld.signed.xml. . .
Signature validation: signtools.ValidateSignedFile
To validate signature, use the command:
java -cp signtools_0_3_0.jar signtools.LaunchValidateSignedFile -ct FileToValidate -b OutputPath . .
- FileToValidate is the file to be validated, generated within the previous tool as OutputFileName.
- OutputPath: Is the path where the embedded file (inside FileToValidate) will be stored.
The tool “java -cp signtools_0_3_0.jar signtools.LaunchValidateSignedFile” performs the validation of the signature, and if everything is OK it also extract the file stored in the object element to a specified folder.
The signature is validated in two phases, according XML Signature validation:
- Cryptographic validation: The signature value is validated against the public key and the digest values.
- Reference validation: Digest of each reference in the signature is validated against referenced data.
java -cp signtools_0_3_0.jar signtools.LaunchValidateSignedFile -ct c:\DEMOS\helloworld.signed.xml -b c:\DEMOS\ . .
Sample output: Signature OK, passed core validation (see line 2 below):
17-oct-2013 14:25:10 signtools.ValidateSignedFile ValidateSignedFile INFO: Signature PASSED core validation 17-oct-2013 14:25:10 signtools.ValidateSignedFile ValidateSignedFile INFO: Writing object 0, id: helloworld.txt mimeType: text/plain encoding: http://www.w3.org/2000/09/xmldsig#base64 at: c:\DEMOS\helloworld.txt . .
Sample output. Now signature is wrong (failed core validation, see line 2 below). In this case, cryptographic validation is OK but reference validation is wrong. Reference (RefFileObject) is wrong, Reference (RefKeyInfo) is OK, and Reference  (RefSignedProperties) is also wrong. So the file object is not the original, the signed properties also aren’t the original but the key info is ok:
17-oct-2013 14:27:34 signtools.ValidateSignedFile ValidateSignedFile ADVERTENCIA: Signature failed core validation 17-oct-2013 14:27:34 signtools.ValidateSignedFile ValidateSignedFile ADVERTENCIA: signature validation status: true 17-oct-2013 14:27:34 signtools.ValidateSignedFile ValidateSignedFile ADVERTENCIA: ID: RefFileObject, reference validity status: true. 17-oct-2013 14:27:34 signtools.ValidateSignedFile ValidateSignedFile ADVERTENCIA: ID: RefKeyInfo, reference validity status: false. 17-oct-2013 14:27:34 signtools.ValidateSignedFile ValidateSignedFile ADVERTENCIA: ID: RefSignedProperties, reference validity status: true. . .
Use of different keys for encryption and signature
Although technically RSA keys generated for encrypting and signing are equivalent (and can be used for both purposes), and sometimes the same keys are used for simplicity in the examples, it is recommended to use different keys for different purposes.
According to NIST SP 800-57 (chapter 5.2), there are several reason for this:
- The use of the same key for two different cryptographic processes may weaken the security provided by one or both of the processes.
- Limiting the use of a key limits the damage that could be done if the key is compromised.
- Some uses of keys interfere with each other. For example, consider a key pair used for both key transport and digital signatures. In this case, the private key is used as both a private key-transport key to decrypt data-encryption keys and a private signature key to apply digital signatures. It may be necessary to retain the private key-transport key beyond the cryptoperiod of the corresponding public key-transport key in order to decrypt the data-encryption keys needed to access encrypted data. On the other hand, the private signature key shall be destroyed at the expiration of its cryptoperiod to prevent its compromise (see Section 5.3.6). In this example, the longevity requirements for the private key-transport key and the private digital-signature key contradict each other.
Full text available at http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf
Use from another program
Two utility classes to easy the call from another program (this is, as a library instead as a command line application) have been prepared: SignFileUtil and ValidateSignedFileUtil.
Sample use of SignFileUtil inside a java code:
SignFileUtil signFileUtil; String keyStoreFile="C:\\DEMOS\\allJKS.jks"; String keyStorePassword="XBRL2013"; String keyStoreAlias="nsa"; String filetoSign="c:\\DEMOS\\files\\helloword.txt"; String outputFile="c:DEMOS\\mytestsfiles\\helloword.txt.signed.xml"; signFileUtil=new SignFileUtil(); signFileUtil.doFileEnvelopingSignature(keyStoreFile, keyStorePassword, keyStoreAlias, filetoSign, outputFile); System.out.println("Signature creation error flag: "+signFileUtil.isErrorFlag()); System.out.println("DONE."); . .
Sample use of ValidateSignedFileUtil inside a java code:
ValidateSignedFileUtil validateFileUtil; String inputFile="c:\\DEMOS\\mytestsfiles\\helloword.txt.signed.xml"; String path="c:\\DEMOS\\mytestsfiles"; validateFileUtil=new ValidateSignedFileUtil(); validateFileUtil.doFileSignatureValidation(inputFile, path); System.out.println("Signature validation error flag: "+validateFileUtil.isErrorFlag()); System.out.println("Output file (the one embedded inside the signature: "+ validateFileUtil.getEmbeddedFileName()+ " (at: "+path+")"); System.out.println("DONE."); . .
Question? Please feel free to contact us: cenwsxbrl at gmail.com