h6n.pl is a proof of concept implementation of the HTML
Signing Profile for XML Signature. The perl script is able to create
signatures that conform to the profile, and to verify these signatures.
The script currently fails if presented with more than one X.509 Certificate, and it does not currently perform Basic Path Validation. I.e., once a signature has been verified, there is no assessment about the trustworthiness of the signature key. Also, rsa-sha1 is the only supported signature algorithm, even though it shouldn't be too difficult to create more flexibility in the future.
h6n.pl depends upon numerous perl modules that are available
on CPAN: LWP::UserAgent; Digest::SHA1; XML::LibXML; Crypt::OpenSSL::RSA;
Crypt::OpenSSL::X509; Crypt::OpenSSL::Random; MIME::Base64; HTML::Parser;
h6n.pl can operate in two distinct modes, sign or verify.
There are corresponding command line parameters, "
-verify". You'll want to make these the first ones.
All "file name" arguments are in fact URI references. Please use
file: URIs for local files.
In order to be able to create signatures with
need to have a self-signed X.509 certificate and the corresponding private
key. The private key must not be protected with a passphrase (this is
proof-of-concept code, remember).
If $who is the subject name for the self-signed certificate, then this is a way to create such files with OpenSSL. Note that this is for demonstration only, so we don't bother with even reasonably long keys, or encrypting the signature key.
openssl req -new -sha1 -newkey rsa:512 -rand /dev/urandom \
-subj "$who" -out my.req
openssl x509 -req -in my.req -signkey privkey.pem \
openssl rsa -in privkey.pem -out key.pem
cert.pem now contains the self-signed certificate.
privkey.pem is the password-protected version of your private
key.pem is the unencrypted version.
To create a signature,
h6n.pl needs at least the following
command line parameters:
h6n.pl is able to deal with multiple variants
for one resource. E.g., the W3C logo at
http://www.w3.org/Icons/w3c_home can actually be a PNG or a GIF
image, depending on content negotiation. To dismabiguate, it is possible to
give URIs for multiple representations of a single resource (assuming there
are other resources that are actually identical to the various
To deal with content negotiated resources, this parameter can be given multiple times.
Putting it all together, to sign the XML Signature specification, relevant inline images, and both variants of the W3C logo, this will do:
./h6n.pl -sign -full -cert file:cert.pem -priv file:key.pem \
-uri http://www.w3.org/TR/xmldsig-core/ \
-rep http://www.w3.org/Icons/w3c_home http://www.w3.org/Icons/w3c_home.png \
-rep http://www.w3.org/Icons/w3c_home http://www.w3.org/Icons/w3c_home.gif \
In the easiest case, a document that is signed has an appropriate
link header that identifies the signature (as this one does). In
this case, the invocation is as simple as:
./h6n.pl -verify -uri http://dev.w3.org/2007/h6n/README.html
The script will discover and verify the signature automatically;
-uri works the same way as for signing.
Additionally, the following optional command line parameteres work: