|
XML Encryption
Example 1. Encrypting
To decrypt data using XML Security Library the application should:
- Create decryption context (depending on the application it could
be done once in the beggining of the program).
- Call decryption functions:
- Verifiy the result and continue decrypted data processing.
In this example, we will decrypt XML document encrypted in
previous example. The source code
for this example is included into the package.
Step 0. Initializing LibXML, OpenSSL and XML Security Library.
Before using the libraries we need to initialize them. This
should be done once in the beginning of your program
int rnd_seed = 0;
/**
* Init OpenSSL:
* this is a BAD way to init random numbers
* generator
*/
while (RAND_status() != 1) {
RAND_seed(&rnd_seed,
sizeof(rnd_seed));
}
/**
* Init libxml
*/
xmlInitParser();
LIBXML_TEST_VERSION
/**
* Init xmlsec
*/
xmlSecInit();
Step 1. Loading key and creating the encryption context.
Before encrypting or decrypting the document you should
create encryption context object. In most case you will need
only one context object per application
xmlSecKeysReadContext keysReadCtx;
xmlSecSimpleKeyMngrPtr keyMgr = NULL;
xmlEncCtxPtr ctx = NULL;
/**
* Create Keys managers
*/
keyMgr = xmlSecSimpleKeyMngrCreate();
if(keyMgr == NULL) {
fprintf(stderr, "Error: failed to create keys
manager\n");
return(-1);
}
/**
* Create Keys Search context
*/
memset(&keysReadCtx, 0, sizeof(keysReadCtx));
keysReadCtx.allowedOrigins = xmlSecKeyOriginAll;
keysReadCtx.findKeyCallback = xmlSecSimpleKeyMngrFindKey;
keysReadCtx.findKeyContext = keyMgr;
keysReadCtx.maxEncKeyLevels = 1; /* limit the infinite recursion
*/
/**
* Create enc context
*/
ctx = xmlEncCtxCreate(&keysReadCtx);
if(ctx == NULL) {
fprintf(stderr, "Error: template failed to
create context\n");
return(-1)
}
/**
* load key private rsa key
*/
if(xmlSecSimpleKeyMngrLoadPrivateKey(keyMgr,
argv[1], NULL, NULL) == NULL) {
fprintf(stderr, "Error: failed to load
key from \"%s\"\n", argv[1]);
return(-1);
}
/**
* Create Keys Search context
*/
memset(&keysReadCtx, 0, sizeof(keysReadCtx));
keysReadCtx.allowedOrigins = xmlSecKeyOriginAll;
keysReadCtx.findKeyCallback = xmlSecSimpleKeyMngrFindKey;
keysReadCtx.findKeyContext = keyMgr;
/**
* Create Signature Context
*/
ctx = xmlEncCtxCreate(&keysReadCtx);
if(dsigCtx == NULL) {
fprintf(stderr,"Error: failed to create
context\n");
return(-1)
}
Step 2. Load the document, decrypt and print result document to
stdout.
We are ready to decrypt the document!
xmlDocPtr doc = NULL;
xmlEncResultPtr result = NULL;
int ret;
/*
* build an XML tree from a the file; we need to
add default
* attributes and resolve all character and entities
references
*/
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
xmlSubstituteEntitiesDefault(1);
doc = xmlParseFile(filename);
if (doc == NULL) {
fprintf(stderr, "Error: unable to parse file \"%s\"\n",
filename);
goto done;
}
/*
* Check the document is of the right kind
*/
if(xmlDocGetRootElement(doc) == NULL) {
fprintf(stderr,"Error: empty document for file
\"%s\"\n", filename);
goto done;
}
/**
* Decrypt
*/
ret = xmlEncDecrypt(ctx, xmlDocGetRootElement(doc), &result);
if(ret < 0) {
fprintf(stderr, "Error: decryption failed\n");
goto done;
}
/**
* And print result to stdout
*/
ret = fwrite(xmlBufferContent(result->buffer),xmlBufferLength(result->buffer),
1, stdout);
Step 3. Cleanup.
At the end we need to destroy encryption context, the doc
and KeysManager; shutdown XML Security Library, libxml and OpenSSL:
/*
* Cleanup
*/
if(ctx != NULL) {
xmlEncCtxDestroy(ctx);
}
if(keyMgr != NULL) {
xmlSecSimpleKeyMngrDestroy(keyMgr);
}
/**
* Shutdown XML Sec
*/
xmlSecShutdown();
/**
* Shutdown libxslt
*/
xsltCleanupGlobals();
/*
* Shutdown libxml
*/
xmlCleanupParser();
/*
* Shutdown OpenSSL
*/
RAND_cleanup();
ERR_clear_error();
Appendix A. The encrypted document.
<?xml version="1.0"?>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>test-rsa-key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>
ETFcDnUPrXyZpaUNDCbe6r6E+YIWmoXBcppWHgv03H+0jIH+w74YKRJh601KUA4u
KDUK/MbglWQ40FvQ4vhOC4X0uGtWizRllOoZJHn9ppzAcIuwURQOIjCNl9GtrcEx
14HNIlUoAEXjIbbwSaGCS5u4IdtxzhS2f9P8INh5PkpJjV9EYT73cbX4Cq5e4Yto
Puox+NUpfOhSfPhTf+41+3u99Nn6oaxlLokfl//lbSE8gD2Yo48cyXN2HkX4tchF
qOFdCb5bYXA/NmLnrdXXm1Fpuf4QoLDXmbfrCXGF+mHSBkVC1C49FL4ynIVGcBF3
FibDfsohFvg/ucbDhKHNVQ==
</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>
BwP8RHXhJ8xcFVSONxfkwOxhgZNElAmJbaaAdzAIjbk=
</CipherValue>
</CipherData>
<EncryptionProperties>
<EncryptionProperty Id="Classified" Level="Top secret"/>
</EncryptionProperties>
</EncryptedData>
Aleksey Sanin
|