Preparing for SCDJWS Part 18: XML Digital Signature and XML Encryption
Today I will talk about XML Digital Signature and XML Encryption.These two are heavily used in Web Services' message level security.
I will show you how to sign and verify XML documents using core (and verbose) Java XML Security API.
Also, I will show you how to sign and verify XML documents and encrypt them using Apache Santuario project.
Theory
You should know what is symmetric and asymmetric key encryption.
Symmetric key encryption uses one master key which is used for both encryption and decryption. In practice exchanging symmetric key must be done in a secure way.
Asymmetric encryption uses always a pair of keys. They are called public and private keys. What is encrypted with public key can be only read using private key and vice-versa, what is encrypted by private key can be decrypted only by a matching public key.
Asymmetric keys are often used to secure symmetric key exchange. Usually client using server's public key encrypts symmetric key and sends it to the server. Only server can decrypt it.
Symmetric key encryption is more efficient and more harder to break than asymmetric keys.
XML Digital Signature prevents your XML document from being tempered with undetected. XML Digital Signature can uses asymmetric encryption.
Here are steps to be done in order to digitally sign XML document:
- canonise XML document - e.g., remove whitespaces, remove comments
- create a digest of such canonised XML document
- sign the digest - using private key or symmetric key
- optional step: public key/certificate may be attached to XML signature
- insert into XML document information about used canonisation algorithms, digest functions, certificates, etc
<Signature />
element looks like this (see example below):<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">To verify XML signature you have to:
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue />
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue />
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate />
</ds:X509Data>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus />
<ds:Exponent />
</ds:RSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
</ds:Signature>
- canonise XML document according to rules found in XML Signature
- compute your own digest, again according to rules found in XML Signature
- if public key/certificate has been attached verify if the certificate is correct
- using public key/certificate decrypt server's digest
- compare computed digest with decrypted one
The XML fragment illustrating it is given below.
XML Digital Signature example
The listing of my
XMLSignatureUtils
and SantuarioXMLSignatureUtils
, and theirs unit tests are too large to copy and paste, thus I decided to present you only the input and outputs (code is available in Download section).Input:
<?xml version="1.0" encoding="UTF-8"?>Digitally signed output:
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/patient patient.xsd" xmlns="http://www.example.org/patient">
<patient>
<firstName>Łukasz</firstName>
<lastName>Budnik</lastName>
<sex>M</sex>
<address>
<city>Wejherowo</city>
<postalCode>84-200</postalCode>
<country>Poland</country>
</address>
</patient>
</data>
<?xml version="1.0" encoding="UTF-8"?>XML Encryption example
<data xmlns="http://www.example.org/patient" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/patient patient.xsd">
<patient>
<firstName>Łukasz</firstName>
<lastName>Budnik</lastName>
<sex>M</sex>
<address>
<city>Wejherowo</city>
<postalCode>84-200</postalCode>
<country>Poland</country>
</address>
</patient>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>mBnqMfJujDQxVtg0/ZYHIVBfAxw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
Hd6+S5AEkk9rBtefjNa7FUX1SDhrGgwaQ/mgptschDBa7+/L9C8Z/hSWd5GiuEva4Oj354GCxF0f
KHtQ4ktR4zqEo7kGvB6FlJdKdRX1/5nRON7THKjMMsHVJb8WSBOOcEYLcrgOuZ1RysvXkS0c9a6A
NTrZ73Jl66wu2Z++HSg=
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIICUTCCAbqgAwIBAgIES1cYIzANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJQTDEQMA4GA1UE
CBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UEChMHVW5rbm93bjEQMA4GA1UECxMH
VW5rbm93bjEWMBQGA1UEAxMNTHVrYXN6IEJ1ZG5pazAeFw0xMDAxMjAxNDUwMTFaFw0xMDA0MjAx
NDUwMTFaMG0xCzAJBgNVBAYTAlBMMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3du
MRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRYwFAYDVQQDEw1MdWthc3ogQnVk
bmlrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4dA3uesGfsfIYEC5xnEhOoZrWhZNiM14h
0OfK9c2tqlByXotFyUf7uME4h654p6xk7puwso3aqtZ8Aw3QUkR7xC/0yR9mbeUdHD0fNoASex5d
+14t3MZ8Vp5Bw1RzoplAEUranKs/sy1yJL/uRDApbD+oiZ7Y2rVXqjg/3xmmjwIDAQABMA0GCSqG
SIb3DQEBBQUAA4GBACRii7DN5tosnKx//PBQAw160SPaA323vsg+aNu9Bto74HR26/2ENK2kP8l7
vnG6phFvf5gbhX77B3hU5y1oGLrCFO9/aWUsfpuwugPKSr4vR6GQisX57+6zR3rG9gfl+Rqx0sCm
nRuFwbqFVHnatPd7mlwYF1uf13D0ceNdkfBN
</ds:X509Certificate>
</ds:X509Data>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus>
uHQN7nrBn7HyGBAucZxITqGa1oWTYjNeIdDnyvXNrapQcl6LRclH+7jBOIeueKesZO6bsLKN2qrW
fAMN0FJEe8Qv9MkfZm3lHRw9HzaAEnseXfteLdzGfFaeQcNUc6KZQBFK2pyrP7MtciS/7kQwKWw/
qIme2Nq1V6o4P98Zpo8=
</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
</ds:Signature>
</data>
Input as above. The encrypted XML document is as follows:
<?xml version="1.0" encoding="UTF-8"?>Complete working download
<data xmlns="http://www.example.org/patient" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/patient patient.xsd">
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<xenc:CipherData>
<xenc:CipherValue>UnnMew4rBxczwumMQTXcmMh/1FRk7ji2JxFVMg/w5wyHqIRhui3z2fCkxqjbdaav9kp5LUCT7Pkr
WVlfxb2OyqnLtfOp2QiD7BSLKG9147EEotS/PZYvCQvnjdc4OfJ9klpd9pL0NeyXyFo10K5023zt
LlLAqF9K2KHelH2iiYQ=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>ZOfjf9hSdKg7IIM2sBLTpEg4YLEcjOKH93G/UwbXC0bHELGNBLVk90+XQw3b3n/Ag4i7amkA3nv3
G9hdi5B2TGshzO5xPkHsOtTnjUibyUrOJmDoXxcPCGFUepaGuByFE8YvVCYc2GHp3oowUJ5wFxyK
eiTlHL2G1OnJs1tvE8Rsa13VP9kzWiQaz433nbFLt8V/GcFa5XzNSfuwOU8h/5F6HTJSR0M2bDKA
UsdGjvPzfvEsyVEo3B4YEv25JiAPRr71/sq/00hYuEsWAGguUeM4wytf0QXxcMtZIzidsbMRuPf7
h8JWkuO/q2tNHWVMuQNZyPP+ld1y8VKAW8/OwaHWG7G8SPy4RbEhsVhJnDBBoVG6m0j7FGnUqLnP
lKKRYD1Mc5uM1w9m0GL5PEmYWehKbzdnty6Hnp3wpVzpEIfx9r9e0hN49B7xpXixjw94</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</data>
Complete working Maven2 project is available here: XML-Security-Digital-Signature-Encryption-Santuario.zip.
Summary
When securing Web Services you don't have to sign/encrypt SOAP messages yourself. You can use for example Project Metro and WSIT technology. See the wsit label on the right.
Next thing will be Username Token Profile, SAML, XACML, XKMS, WS-Security, Liberty Project, and WS-Policy.
Take care,
Łukasz
Комментариев нет:
Отправить комментарий