Security
- HTTP over SSL (including the SSL certificate handling)
- xml digital signature (signing and validating) (including certificate handling)
- xml encryption/decryption (including certificate handling)
- see http://www.aleksey.com/xmlsec/index.html
Search web for
- [xmlsec] Handling CID: moniker to sign attachments
- SV: [xmlsec] Using a content ID for URI
Maybe use OpenSSL as the PKI infrastructure.
XML Digital Signature
The structure of a XML Digital Signature elements:
<Signature> <SignedInfo> (CanonicalizationMethod) (SignatureMethod) (<Reference (URI=)? > (Transforms)? (DigestMethod) (DigestValue) </Reference>)+ </SignedInfo> (SignatureValue) (KeyInfo)? (Object)* </Signature>
Enveloped
<house> <front-door/> <rear-door/> <signature> </signature> </house>
Enveloping
<signature>
<house>
<front-door/>
<rear-door/>
</house>
</signature>
Detached
not required now.
Passphrases
In order to create private keys it is important to have good passphrases.
openssl rand 15 -base64
resource: http://www.linuxjournal.com/node/8958/print
Keys
You can use the OPENSSL toolkit (http://www.openssl.org/) to generate/manipulate keys.
openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [-f4] [-3] [-rand file(s)] [-engine id] [numbits]
Generating an RSA key
for example (passphrase is the passphrase). The following example will geerate a key in the PEM (default) format.
sacha@HefeWeizen/trunk/doc/xmldsig$ openssl genrsa -out my_private_key -des3 1024 Generating RSA private key, 1024 bit long modulus ........................++++++ .++++++ e is 65537 (0x10001) Enter pass phrase for my_private_key: passphrase Verifying - Enter pass phrase for my_private_key: passphrase
To look at the private key:
sacha@HefeWeizen/trunk/doc/xmldsig$ cat my_private_key -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,F9482F4F13362513 Kbg3WXgfagBJsF7AWzkivKLyIW6gpN0EvSoRv0nO0uQxYIWDSFh1TizlF934u+Eu 6AzQ1lCNIH8JRMx3RUh07JMCKzmB2ikUC3WObhwBQuQcdEDQKoBqt2VefHK5VnN8 0ubFC+A6msFXrWCSKThTmqiSFqiUIv2mWxhwCwwmvYZnKsYYYFrAtTmBaBrFQY0o OTOT9FSX4GrVYqOKJzEn7ylNZ0pjLdd7JvgKFS+wDzkK/9i2YIJOP4UlfeRb/fYE GohKGNirCcz8XA4V2Se9IPTdxWxnPeHl9jbkbDFSvkqSR9qi8EtP2MwDpcWRF0rk +s82/nxL5U3oRF1tHHIDprEFRRnbB1fGgadeWpAMLebOaO00suF22mv4HRPZFYUL 7F5tCAHbyH+i3ScWu9X02o6PuxY+uBq3VKNDLVjKQpGArr2mM4CfmnEYs8FvDbvk 1Gg0Xakw2VG67S8pVsMmXSphQk8Z5O2FF5TP8pMy7Y+XQDHIvWMdPODZomW3iZyj 9UqDfvc1S5/GM3B5xMxFWzEAxa9j/hBA9B8hd4nCFQtmyXnXoSa3ulRVZAqrlSiG ehHnby4KScZWcDy6vGQZtVHLa83WdjpqM6tqsAo+WLynVB/7u5YYf4gmFBVNueSZ mw1sxc2vTJ+bhfqPPf2AqkctmEOLFymMbEQJxLk8Uf4Ud3hf2BVQLNzjc64yo9J1 3GpZ2mTx6xwlZ13C02CUW45XdvcZf3YPKUSWutodNhoUuA7DI7Cn/ipRSn8m+otJ 3qEE3PlErfWttm7TyTkk4CqwhaAP+gcwhvNh3f6qrl0= -----END RSA PRIVATE KEY-----
Removing the passphrase from a private key
For an automated system it is not possible that a user must provide the passphrase everytime the HTTPS server starts or whenever a user wants to send an message with wget. The curl toolkit seems to have a --pass option to pass in the passphrase but not wget.
The following command makes a copy of the private key and stores it without a passphrase.
mv my_private_key my_private_key_with_passphrase openssl rsa -in my_priate_key -out my_private_key_without_passphrase
This is less secure than using a passphrase. Potentially a private key store with one passphrase but where the individual private keys have no passphrase would make it acceptable. The user of the system would then need to provide a passphrase to open the private key store ... that passphrase could be part of a configuration setup.
Generating the public key of it
To look at the public key of the just generated key use the following command.
sacha@coronation:/HefeWeizen/trunk/doc/xmldsig$ openssl rsa -pubout <my_private_key >my_public_key Enter pass phrase: writing RSA key sacha@coronation:/HefeWeizen/trunk/doc/xmldsig$ cat my_public_key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHgDR70DxNIgRMjaFhKAno8cz1 iELuRtKmMcI+ClU/YtcMem7J865ETv1gu2QyiJK1CYGg7h50Gausb0VLs27k34P6 AxVxpnC3Ok4P16l2mkRUTtpozbTvC+JVUXpLBIz2m1HGHYQc6fhc9CdpglUTD0Ga MZYud/WQGJzOr0B9MQIDAQAB -----END PUBLIC KEY-----
Creating a self signed x509 certificate
We can have our private key signed by an authorized certification authority. But for testing purposes we can also selfsign the key.
sacha@coronation:/HefeWeizen/trunk/doc/xmldsig$ openssl req -new -x509 -key my_private_key -out cacert.pem -days 1095 Enter pass phrase for my_private_key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:LI State or Province Name (full name) [Some-State]:Balzers Locality Name (eg, city) []:Balzers Organization Name (eg, company) [Internet Widgits Pty Ltd]:HavanaWave AG Organizational Unit Name (eg, section) []:B2B Common Name (eg, YOUR name) []:Sacha Schlegel Email Address []:sacha.schlegel@havanawave.com
lets have a look at the cacert.pem file:
sacha@coronation:~/havanawave/projects/software-development/HefeWeizenProject/HefeWeizen/trunk/doc/xmldsig$ cat cacert.pem -----BEGIN CERTIFICATE----- MIIDxTCCAy6gAwIBAgIJALk56Oe6QWFhMA0GCSqGSIb3DQEBBQUAMIGeMQswCQYD VQQGEwJMSTEQMA4GA1UECBMHQmFsemVyczEQMA4GA1UEBxMHQmFsemVyczEWMBQG A1UEChMNSGF2YW5hV2F2ZSBBRzEMMAoGA1UECxMDQjJCMRcwFQYDVQQDEw5TYWNo YSBTY2hsZWdlbDEsMCoGCSqGSIb3DQEJARYdc2FjaGEuc2NobGVnZWxAaGF2YW5h d2F2ZS5jb20wHhcNMDYxMTI3MTA0NDMzWhcNMDkxMTI2MTA0NDMzWjCBnjELMAkG A1UEBhMCTEkxEDAOBgNVBAgTB0JhbHplcnMxEDAOBgNVBAcTB0JhbHplcnMxFjAU BgNVBAoTDUhhdmFuYVdhdmUgQUcxDDAKBgNVBAsTA0IyQjEXMBUGA1UEAxMOU2Fj aGEgU2NobGVnZWwxLDAqBgkqhkiG9w0BCQEWHXNhY2hhLnNjaGxlZ2VsQGhhdmFu YXdhdmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHgDR70DxNIgRM jaFhKAno8cz1iELuRtKmMcI+ClU/YtcMem7J865ETv1gu2QyiJK1CYGg7h50Gaus b0VLs27k34P6AxVxpnC3Ok4P16l2mkRUTtpozbTvC+JVUXpLBIz2m1HGHYQc6fhc 9CdpglUTD0GaMZYud/WQGJzOr0B9MQIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFNhK BU0esnTtM2vqm93EOcCgat7oMIHTBgNVHSMEgcswgciAFNhKBU0esnTtM2vqm93E OcCgat7ooYGkpIGhMIGeMQswCQYDVQQGEwJMSTEQMA4GA1UECBMHQmFsemVyczEQ MA4GA1UEBxMHQmFsemVyczEWMBQGA1UEChMNSGF2YW5hV2F2ZSBBRzEMMAoGA1UE CxMDQjJCMRcwFQYDVQQDEw5TYWNoYSBTY2hsZWdlbDEsMCoGCSqGSIb3DQEJARYd c2FjaGEuc2NobGVnZWxAaGF2YW5hd2F2ZS5jb22CCQC5OejnukFhYTAMBgNVHRME BTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAIw0ZuzWHOxGavoC+CxmLmlNtsMeOP5Y q9gsc3nH/f3MZpeeT33a8JOz6c/keNZw8QKKAvmyCUAlE2RHxeYjsWm5YYWQqu6/ re2rxVxtJ2GXm6K1eM7GvaE32okRQPDTwl6XVnVjHTQvQQ2zd1/jNNuhhdfEjLNc Xv1vZnRfWlkF -----END CERTIFICATE-----
There is much more in this ... lets see at the certificate information with
sacha@coronation:/HefeWeizen/trunk/doc/xmldsig$ openssl x509 -text -in cacert.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
b9:39:e8:e7:ba:41:61:61
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=LI, ST=Balzers, L=Balzers, O=HavanaWave AG, OU=B2B, CN=Sacha Schlegel/emailAddress=sacha.schlegel@havanawave.com
Validity
Not Before: Nov 27 10:44:33 2006 GMT
Not After : Nov 26 10:44:33 2009 GMT
Subject: C=LI, ST=Balzers, L=Balzers, O=HavanaWave AG, OU=B2B, CN=Sacha Schlegel/emailAddress=sacha.schlegel@havanawave.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:c7:80:34:7b:d0:3c:4d:22:04:4c:8d:a1:61:28:
09:e8:f1:cc:f5:88:42:ee:46:d2:a6:31:c2:3e:0a:
55:3f:62:d7:0c:7a:6e:c9:f3:ae:44:4e:fd:60:bb:
64:32:88:92:b5:09:81:a0:ee:1e:74:19:ab:ac:6f:
45:4b:b3:6e:e4:df:83:fa:03:15:71:a6:70:b7:3a:
4e:0f:d7:a9:76:9a:44:54:4e:da:68:cd:b4:ef:0b:
e2:55:51:7a:4b:04:8c:f6:9b:51:c6:1d:84:1c:e9:
f8:5c:f4:27:69:82:55:13:0f:41:9a:31:96:2e:77:
f5:90:18:9c:ce:af:40:7d:31
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
D8:4A:05:4D:1E:B2:74:ED:33:6B:EA:9B:DD:C4:39:C0:A0:6A:DE:E8
X509v3 Authority Key Identifier:
keyid:D8:4A:05:4D:1E:B2:74:ED:33:6B:EA:9B:DD:C4:39:C0:A0:6A:DE:E8
DirName:/C=LI/ST=Balzers/L=Balzers/O=HavanaWave AG/OU=B2B/CN=Sacha Schlegel/emailAddress=sacha.schlegel@havanawave.com
serial:B9:39:E8:E7:BA:41:61:61
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
8c:34:66:ec:d6:1c:ec:46:6a:fa:02:f8:2c:66:2e:69:4d:b6:
c3:1e:38:fe:58:ab:d8:2c:73:79:c7:fd:fd:cc:66:97:9e:4f:
7d:da:f0:93:b3:e9:cf:e4:78:d6:70:f1:02:8a:02:f9:b2:09:
40:25:13:64:47:c5:e6:23:b1:69:b9:61:85:90:aa:ee:bf:ad:
ed:ab:c5:5c:6d:27:61:97:9b:a2:b5:78:ce:c6:bd:a1:37:da:
89:11:40:f0:d3:c2:5e:97:56:75:63:1d:34:2f:41:0d:b3:77:
5f:e3:34:db:a1:85:d7:c4:8c:b3:5c:5e:fd:6f:66:74:5f:5a:
59:05
-----BEGIN CERTIFICATE-----
MIIDxTCCAy6gAwIBAgIJALk56Oe6QWFhMA0GCSqGSIb3DQEBBQUAMIGeMQswCQYD
VQQGEwJMSTEQMA4GA1UECBMHQmFsemVyczEQMA4GA1UEBxMHQmFsemVyczEWMBQG
A1UEChMNSGF2YW5hV2F2ZSBBRzEMMAoGA1UECxMDQjJCMRcwFQYDVQQDEw5TYWNo
YSBTY2hsZWdlbDEsMCoGCSqGSIb3DQEJARYdc2FjaGEuc2NobGVnZWxAaGF2YW5h
d2F2ZS5jb20wHhcNMDYxMTI3MTA0NDMzWhcNMDkxMTI2MTA0NDMzWjCBnjELMAkG
A1UEBhMCTEkxEDAOBgNVBAgTB0JhbHplcnMxEDAOBgNVBAcTB0JhbHplcnMxFjAU
BgNVBAoTDUhhdmFuYVdhdmUgQUcxDDAKBgNVBAsTA0IyQjEXMBUGA1UEAxMOU2Fj
aGEgU2NobGVnZWwxLDAqBgkqhkiG9w0BCQEWHXNhY2hhLnNjaGxlZ2VsQGhhdmFu
YXdhdmUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHgDR70DxNIgRM
jaFhKAno8cz1iELuRtKmMcI+ClU/YtcMem7J865ETv1gu2QyiJK1CYGg7h50Gaus
b0VLs27k34P6AxVxpnC3Ok4P16l2mkRUTtpozbTvC+JVUXpLBIz2m1HGHYQc6fhc
9CdpglUTD0GaMZYud/WQGJzOr0B9MQIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFNhK
BU0esnTtM2vqm93EOcCgat7oMIHTBgNVHSMEgcswgciAFNhKBU0esnTtM2vqm93E
OcCgat7ooYGkpIGhMIGeMQswCQYDVQQGEwJMSTEQMA4GA1UECBMHQmFsemVyczEQ
MA4GA1UEBxMHQmFsemVyczEWMBQGA1UEChMNSGF2YW5hV2F2ZSBBRzEMMAoGA1UE
CxMDQjJCMRcwFQYDVQQDEw5TYWNoYSBTY2hsZWdlbDEsMCoGCSqGSIb3DQEJARYd
c2FjaGEuc2NobGVnZWxAaGF2YW5hd2F2ZS5jb22CCQC5OejnukFhYTAMBgNVHRME
BTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAIw0ZuzWHOxGavoC+CxmLmlNtsMeOP5Y
q9gsc3nH/f3MZpeeT33a8JOz6c/keNZw8QKKAvmyCUAlE2RHxeYjsWm5YYWQqu6/
re2rxVxtJ2GXm6K1eM7GvaE32okRQPDTwl6XVnVjHTQvQQ2zd1/jNNuhhdfEjLNc
Xv1vZnRfWlkF
-----END CERTIFICATE-----
Something interesting is the Signature Algorithm: sha1WithRSAEncryption
Preparing the XML document to be signed
The way xml digital signature is working is that the user (or the application) has to add signature structure and metadata into the xml document first. This metadata includes the selection of the algorithms for example. When the user (or the application) invokes the signing process the tool (xmlsec for example) reads the metadata in the signature skeleton structure and fills the signature structure accordingly (with the signed hash value for example).
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://www.oasis-open.org/committees/ebxml-msg/schema/envelope.xsd">
<soap-env:Header xsi:schemaLocation="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd">
<eb:MessageHeader xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" soap-env:mustUnderstand="1" eb:version="2.0">
<eb:From>
<eb:PartyId eb:type="string">gnaraloo</eb:PartyId>
</eb:From>
<eb:To>
<eb:PartyId eb:type="string">coronation</eb:PartyId>
</eb:To>
<eb:CPAId>Coronation::Gnaraloo::UBL 1.0 Small Business Subset Order With Simple Response::1</eb:CPAId>
<eb:ConversationId>1164384938.42779</eb:ConversationId>
<eb:Service>urn:oasis:names:tc:ebxml-msg:service</eb:Service>
<eb:Action>MessageError</eb:Action>
<eb:MessageData>
<eb:MessageId>20061124-161539278-Coronation::Gnaraloo::UBL 1.0 Small Business Subset Order With Simple Response::1.urn:oasis:names:tc:ebxml-msg:service.MessageError.1@127.0.0.1</eb:MessageId>
<eb:Timestamp>2006-11-24T16:15:39Z</eb:Timestamp>
<eb:RefToMessageId>1164384938.42781@Coronation</eb:RefToMessageId>
</eb:MessageData>
</eb:MessageHeader>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<XPath>not(ancestor-or-self::node()[@soap-env:actor="urn:oasis:names:tc:ebxml-msg:actor:next=MSH"] | ancestor-or-self::node()[@soap-env:actor="http://schemas.xmlsoap.org/soap/actor/next"])
</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
</SignatureValue>
<KeyInfo>
</KeyInfo>
</Signature>
<eb:ErrorList xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" soap-env:mustUnderstand="1" eb:version="2.0" eb:highestSeverity="Error">
<eb:Error eb:errorCode="ValueNotRecognized" eb:severity="Error">
<eb:Description xml:lang="en-US">Application context (CPAId)=Coronation::Gnaraloo::UBL 1.0 Small Business Subset Order With Simple Response::1, (ConversationId)=1164384938.42779, (Service)=Create Order, (Action)=Send Order UBL 1.0 SBS Order cannot be recognized.</eb:Description>
</eb:Error>
</eb:ErrorList>
</soap-env:Header>
<soap-env:Body xsi:schemaLocation="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd"/>
</soap-env:Envelope>
What to sign
The URI attribute of the Reference element tells the signing toolkit what to include in the signature. It is possible to have multiple such References.
If the URI attribute value is some ID then we have to help xmlsec as described in the xmlsec FAQ (see section 3.2 at http://www.aleksey.com/xmlsec/faq.html).
EbXML messages are somewhat special as they are multipart mime messages. In the first mime part is the SOAP message which includes the ebXML message (header and body). The ebXML message header includes the signature. For a typcial ebXML User message the user wants to sign the SOAP message (includes the acutal ebXML message) PLUS the other mime parts (basically the payloads). So for each mime part we do need to as a Reference element so that the toolkit also signs that part. Now the problem is that this is no longer in the same XML document and the XML toolkit fails.
The solution is (has to be developed for HefeWeizen) to follow the instructions bye the xmlsec developers (see http://www.aleksey.com/pipermail/xmlsec/2003/001551.html) to write and register a handler for xmlsec and libxml2 that exposes three functions to a) open the stream to the content (via the URI attribute of the Reference element), b) read the stream, and c) close the stream.
Signing the XML document
In a nutshell: transforming the XML to a canonicalized version of XML (no breaks, empty lines between tags, removing comment from xml, more), calculating the hash, generating a key, asymetric encryption of the hash with the generated key, symetric encryption of the key with the senders private key, sticking everything into the XML document again.
xmlsec1 --sign --privkey-pem my_private_key --output signed_message.xml nice-error-message.xml
this results in the following signed_message.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://www.oasis-open.org/committees/ebxml-msg/schema/envelope.xsd">
<soap-env:Header xsi:schemaLocation="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd">
<eb:MessageHeader xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" soap-env:mustUnderstand="1" eb:version="2.0">
<eb:From>
<eb:PartyId eb:type="string">gnaraloo</eb:PartyId>
</eb:From>
<eb:To>
<eb:PartyId eb:type="string">coronation</eb:PartyId>
</eb:To>
<eb:CPAId>Coronation::Gnaraloo::UBL 1.0 Small Business Subset Order With Simple Response::1</eb:CPAId>
<eb:ConversationId>1164384938.42779</eb:ConversationId>
<eb:Service>urn:oasis:names:tc:ebxml-msg:service</eb:Service>
<eb:Action>MessageError</eb:Action>
<eb:MessageData>
<eb:MessageId>20061124-161539278-Coronation::Gnaraloo::UBL 1.0 Small Business Subset Order With Simple Response::1.urn:oasis:names:tc:ebxml-msg:service.MessageError.1@127.0.0.1</eb:MessageId>
<eb:Timestamp>2006-11-24T16:15:39Z</eb:Timestamp>
<eb:RefToMessageId>1164384938.42781@Coronation</eb:RefToMessageId>
</eb:MessageData>
</eb:MessageHeader>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<XPath>not(ancestor-or-self::node()[@soap-env:actor="urn:oasis:names:tc:ebxml-msg:actor:next=MSH"] | ancestor-or-self::node()[@soap-env:actor="http://schemas.xmlsoap.org/soap/actor/next"])
</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>1zwP+ZCsADrebc3EOtekMvYZFus=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>dmCHbUN2XxPyk7LU+MhKc8JRV22RduakR/bYQJPmi8oQvzRlKFmVagvoxqe0Shy/
zHWOyDnHtMnXS3SFoLtCjXlCnCdyw1A+dGMLkq+S1MH5c/bElX8Sx+ZaDzRicl3T
PKy33xFIPXJiPiBF9RBwQG+SZD32xdGRZhV6A+vG2Xc=</SignatureValue>
<KeyInfo>
</KeyInfo>
</Signature>
<eb:ErrorList xmlns:eb="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd" soap-env:mustUnderstand="1" eb:version="2.0" eb:highestSeverity="Error">
<eb:Error eb:errorCode="ValueNotRecognized" eb:severity="Error">
<eb:Description xml:lang="en-US">Application context (CPAId)=Coronation::Gnaraloo::UBL 1.0 Small Business Subset Order With Simple Response::1, (ConversationId)=1164384938.42779, (Service)=Create Order, (Action)=Send Order UBL 1.0 SBS Order cannot be recognized.</eb:Description>
</eb:Error>
</eb:ErrorList>
</soap-env:Header>
<soap-env:Body xsi:schemaLocation="http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd"/>
</soap-env:Envelope>
Validating the signed XML document
coronation:/home/sacha/HefeWeizen/doc/xmldsig# xmlsec1 verify --pubkey-pem my_private_key signed_message.xml Enter password for "my_private_key" file: passphrase OK SignedInfo References (ok/all): 1/1 Manifests References (ok/all): 0/0
Where the main OK indicates that everything is fine.
Failed validation
When changing something in the signed_message.xml file and verifiy the digital sigature we get the following error:
coronation:/home/sacha/HefeWeizen/doc/xmldsig# xmlsec1 verify --pubkey-pem my_private_key signed_message.xml Enter password for "my_private_key" file: passphrase func=xmlSecOpenSSLEvpDigestVerify:file=digests.c:line=229:obj=sha1:subj=unknown:error=12:invalid data:data and digest do not match FAIL SignedInfo References (ok/all): 0/1 Manifests References (ok/all): 0/0 Error: failed to verify file "signed_message.xml"
Where the FAIL indiates that the signature failed to validate.
XML Encryption
XML encryption and decryption are straight forward. A note on encryption: A party A has to send a file X to party B. Party A normally does not encrypt file X with Party B's public key but creates a session key, encrypts file X with the session key and then encrypts the session key with Party B's public key. The reason is that encryption and decryption of data is faster with symtric cryptography than with asymetric cryptographic. The Public and Private Key cryptograhpy is asymetric cryptography.
How XML encryption
In XML encryption the result will be put into an XML file. There are different ways how to encrypt data and so the user has to tell the tool how to encrypt the data. This is done by providing a template.
<?xml version="1.0" encoding="UTF-8"?>
<!--
XML Security Library example: XML doc file encrypted with DES sym key =
then transported using xmlenc#rsa-1_5=20
-->
<EncryptedData Id="ED" xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey Id="EK" xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>Key Name. Not really important.</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue />
</CipherData>
</EncryptedKey>
</ds:KeyInfo>
<CipherData>
<CipherValue />
</CipherData>
</EncryptedData>
This template indicates that the XML encryption toolkit shall use tripledes for the symteric encryption. Then the key shall be encrypted with the algorithm rsa-1_5 where the receivers public key will be needed. The following line shows how to call xmlsec1 to encrypt a binary file.
xmlsec1 encrypt --binary-data /usr/src/linux-source-2.6.18.tar.bz2 --session-key des-192 --pubkey-pem coronation_encryption_cert/Coronation_encryption_public_key.pem --output out2.xml template2.xml
The file out2.xml is now the file that can be sent to the receiver. The receiver than has to decrypt the file with the following command:
xmlsec1 decrypt --privkey-pem coronation_encryption_cert/Coronation_encryption_private_key.pem --output linux-source-2.6.18.tar.bz2 out2.xml
This procedure will encrypt the source of the Linux Kernel (of course the file must exist). This example file is about 42 MByte large; so rather a large file to exchange. On a Core2 Duo T7200 @ 2.0GHz laptop with 2 GB Ram the encryption and decryption took roughly about 12 seconds.
XML Digital Signature AND Encryption
Based on ebXML Message Service Version 2.0 Specification: Signature first, followed by the encryption.
