Mega Code Archive
Encryption
Title: Encryption.
Question: This article introduces the working sample code in Borland Delphi which implements digitally singing and encrypting XML documents with XML Security library using certificates from a file.
Answer:
Examples of signing and encrypting XML documents using XML Security Library by Aleksey Sanin (http://www.aleksey.com/xmlsec/) using Pascal units from http://sourceforge.net/projects/libxml2-pas:
For encrypting:
procedure xmlEncEnKrypt(const key_file, tmpl_file: PChar;
const _nodeForCryptingStr, _output, _pass: string;
_format: xmlSecKeyDataFormat; var _ok: Boolean);
var
doc: xmlDocPtr;
encCtx: xmlSecEncCtxPtr;
_encData, keyInfoNode, encKeyNode, keyInfoNode2, _nodeForCryptingPtr: xmlNodePtr;
buffer: PChar;
bufSize: integer;
mngr: xmlSecKeysMngrPtr;
key: xmlSecKeyPtr;
_pom: TStringList;
begin
encCtx := nil;
mngr := nil;
doc := nil;
key := nil;
_ok := False;
try
doc := xmlParseFile(tmpl_file);
if Doc = nil then
raise Exception.Create('Error: Can not open: ' + tmpl_file);
_encdata := xmlSecTmplEncDataCreate(doc, xmlSecTransformDes3CbcGetKlass,
Nil, xmlSecTypeEncElement, Nil, nil);
if _encdata = nil then
raise Exception.Create('Error: Can not create ');
if(xmlSecTmplEncDataEnsureCipherValue(_encdata) = Nil) then
raise Exception.Create('Error: Can not create CipherValue node');
keyInfoNode := xmlSecTmplEncDataEnsureKeyInfo(_encdata, nil);
if keyInfoNode = nil then
raise Exception.Create('Error: Can not create keyInfoNode');
encKeyNode := xmlSecTmplKeyInfoAddEncryptedKey(keyInfoNode,
xmlSecTransformRsaPkcs1GetKlass,
NiL, NiL, NiL);
if encKeyNode = nil then
raise Exception.Create('Error: Can not create encKeyNode');
if(xmlSecTmplEncDataEnsureCipherValue(encKeyNode) = Nil) then
raise Exception.Create('Error: Can not add CipherValue node');
keyInfoNode2 := xmlSecTmplEncDataEnsureKeyInfo(encKeyNode, NiL);
if keyInfoNode2 = nil then
raise Exception.Create('Error: Can not create keyInfoNode2');
mngr := xmlSecKeysMngrCreate();
xmlSecCryptoAppDefaultKeysMngrInit(mngr);
if _pass='' then
key := xmlSecCryptoAppKeyLoad(key_file, _format, nil, NiL, NiL)
else
key := xmlSecCryptoAppKeyLoad(key_file, _format, PChar(_pass), NiL, NiL);
if key = nil then
raise Exception.Create('Error: Can not open key.');
xmlSecKeySetName(key, key_file);
xmlSecCryptoAppDefaultKeysMngrAdoptKey(mngr, key);
encCtx := xmlSecEncCtxCreate(mngr);
encCtx.encKey := xmlSecKeyGenerate(xmlSecKeyDataDesGetKlass, 192, 192);
if encCtx.encKey = nil then
raise Exception.Create('Error: Can not generate key.');
_nodeForCryptingPtr := xmlSecFindNode(xmlDocGetRootElement(doc), PChar(_nodeForCryptingStr), nil);
if _nodeForCryptingPtr = nil then
raise Exception.Create('Error: Can not find ' + _nodeForCryptingStr);
if xmlSecEncCtxXmlEncrypt(encCtx, _Encdata,_nodeForCryptingPtr)0 then
raise Exception.Create('Error at the encrypting data.');
buffer := nil;
xmlDocDumpMemory(doc, @buffer, @bufSize);
if (buffer nil) then
begin
_pom := TStringList.Create;
_pom.Text := PChar(buffer);
_pom.SaveToFile(_output);
FreeAndNil(_pom);
xmlFree(buffer);
end;
_ok:=True;
finally
if (doc nil) then
xmlFreeDoc(doc);
if mngr nil then
xmlSecKeysMngrDestroy(mngr);
if encCtx nil then
xmlSecEncCtxDestroy(encCtx);
end;
end;
For signing:
procedure xmlEncSign(const tmpl_file, key_file: PChar; _output, _pass: string; _format: xmlSecKeyDataFormat; var _ok: Boolean);
var
doc: xmlDocPtr;
encCtx: xmlSecEncCtxPtr;
Node: xmlNodePtr;
dsigCtx: xmlSecDSigCtxPtr;
buffer: PChar;
bufSize: integer;
mngr: xmlSecKeysMngrPtr;
key: xmlSecKeyPtr;
_pom: TStringList;
begin
doc := nil;
node := nil;
dsigCtx := nil;
_ok := False;
if (tmpl_file = nil) or (key_file = nil) then
raise Exception.Create('Wrong params!');
try
doc := xmlParseFile(tmpl_file);
if Doc = nil then
raise Exception.Create('Error: Can not find: ' + tmpl_file);
node := xmlSecFindNode(xmlDocGetRootElement(doc), PChar(xmlSecNodeSignature), PChar(xmlSecDSigNs));
if node = nil then
raise Exception.Create('Error: Can not find: ' + xmlSecNodeSignature);
dsigCtx := xmlSecDSigCtxCreate(nil);
dsigCtx.signKey := xmlSecCryptoAppKeyLoad(key_file, _format, PChar(_pass), nil, nil);
if dsigCtx.signKey = nil then
raise Exception.Create('Error: Can not open key.');
if (xmlSecKeySetName(dsigCtx.signKey, key_file) raise Exception.Create('Error: Can not set key name from: "' + key_file + '"');
if (xmlSecDSigCtxSign(dsigCtx, node) raise Exception.Create('Error: Unsuccessfull singing.');
buffer := nil;
xmlDocDumpMemory(doc, @buffer, @bufSize);
if (buffer nil) then
begin
_pom := TStringList.Create;
_pom.Text := PChar(buffer);
_pom.SaveToFile(_output);
FreeAndNil(_pom);
xmlFree(buffer);
end;
_ok:=True;
finally
if dsigCtx nil then
xmlSecDSigCtxDestroy(dsigCtx);
end
end;