Changes

Jump to navigation Jump to search
8,716 bytes added ,  12:32, 8 May 2024
no edit summary
This module contains [[Querying#FunctionsModule Library|XQuery functionsModule]] contains functions to perform cryptographic operations in XQuery. The cryptographic module is based on an early draft of the [http://expath.org/spec/crypto /20110810 EXPath Cryptographic Module] and provides the following functionality:# Creation creation of message authentication codes (HMAC)# Creation , encryption and decryption, and creation and validation of an XML Digital SignatureSignatures. =Conventions=# Encryption and decryptionThis All functions in this module are assigned to the <code><nowiki>http://expath.org/ns/crypto</nowiki></code> namespace, which is introduced with statically bound to the {{Code|crypto}} prefix.<br/>All errors are assigned to the <font color='orangered'code><nowiki>Version 7http://expath.0org/ns/error</fontnowiki> of BaseX</code> namespace, which is statically bound to the {{Code|experr}} prefix=Message Authentication=
==crypto:hmac==
{|
|-
| valign='top' width='90' | '''Signatures'''
|<code><b>crypto:hmac</b>($message as xs:string(), $secret-key as xs:string(), algorithm as xs:string()) as xs:string()</code><br/><code><b>crypto:hmac</b>($message as xs:string(), $secret-key as xs:string(), algorithm as xs:string(), $encoding as xs:string()) as xs:string()</code>
|-
| valign='top' | '''Summary'''
|Creates a message authentication code via a cryptographic hash function and a secret key. <br/><code>$encoding</code> must either be <code>hex</code>, <code>base64</code> or the empty string (default is <code>base64</code>) and specifies the encoding of the returned authentication code.<br/><code>$algorithm</code> describes the hash algorithm which is used for encryption. Currently supported are <code>md5</code>, <code>sha1</code>, <code>sha256</code>, <code>sha384</code>, <code>sha512</code>.
|-
| valign='top' | '''Errors'''
|<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0013]]</b> is raised if the specified hashing algorithm is not supported.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0014]]</b> is raised if the specified encoding method is not supported.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0019]]</b> is raised if the specified secret key is invalid.<br/>
|-
| valign='top' | '''Example'''
|'''Returns the message authentication code (MAC) for a given string.'''
{| width='100%'
|- valign="top"
| width='120' | '''Signature'''
|<pre>crypto:hmac(
$data as xs:anyAtomicType,
$key as xs:anyAtomicType,
$algorithm as xs:string,
$encoding as xs:string := ()
) as xs:string</pre>
|- valign="top"
| '''Summary'''
|Creates an authentication code for the specified {{Code|$data}} via a cryptographic hash function:
* {{Code|$key}} must not be empty.
* {{Code|$algorithm}} describes the hash algorithm which is used for encryption. Currently supported are {{Code|md5}}, {{Code|sha1}}, {{Code|sha256}}, {{Code|sha384}}, {{Code|sha512}}. Default is {{Code|md5}}.
* {{Code|$encoding}} must either be {{Code|hex}} or {{Code|base64}}; it specifies the encoding of the returned authentication code. Default is {{Code|base64}}.
|- valign="top"
| '''Errors'''
|{{Error|CX0013|#Errors}} the specified hashing algorithm is not supported.<br/>{{Error|CX0014|#Errors}} the specified encoding method is not supported.<br/>{{Error|CX0019|#Errors}} the specified secret key is invalid.<br/>
|- valign="top"
| '''Example'''
|Return message authentication code (MAC) for a given string:
'''Query:'''
<pre classlang="brush:'xquery"'>crypto:hmac('message','secretkey','md5','base64hex')
</pre>
'''Result:'''
<pre classlang="brush:xml">
34D1E3818B347252A75A4F6D747B21C2
</pre>
|}
 
=Encryption & Decryption=
 
The encryption and decryption functions underlie several limitations:
* Cryptographic algorithms are currently limited to {{Code|symmetric}} algorithms. This means that the same secret key is used for encryption and decryption.
* Available algorithms are {{Code|DES}} and {{Code|AES}}.
* Padding is fixed to {{Code|PKCS5Padding}}.
* The result of an encryption using the same message, algorithm and key looks different each time it is executed. This is due to a random initialization vector (IV) which is appended to the message and simply increases security.
* As the IV has to be passed along with the encrypted message somehow, data which has been encrypted by the {{Code|crypto:encrypt}} function in BaseX can only be decrypted by calling the {{Code|crypto:decrypt}} function.
==crypto:encrypt==
{|
|-
| valign='top' width='90' | '''Signatures'''
|<code><b>crypto:encrypt</b>($input as xs:string(), $encryption-type as xs:string(), $secret-key as xs:string(), $cryptographic-algorithm as xs:string()) as xs:string()</code>
|-
| valign='top' | '''Summary'''
|Encrypts the given input string.<br/>
<code>$encryption-type</code> must be <code>symmetric</code>, as asymmetric encryption is not supported so far.<br/>
<code>$secret-key</code> is the secret key which is used for both encryption and decryption of input data. Its length is fixed and depends on the chosen algorithm: <code>8 bytes for DES</code>, <code>16 bytes for AES</code>.<br/>
<code>$cryptographic-algorithm</code> can be <code>DES</code> and <code>AES</code>. Other algorithms are not supported so far, but, of course, can be added on demand.
|-
| valign='top' | '''Errors'''
|<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0016]]</b> is raised if padding problems arise.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0017]]</b> is raised if padding is incorrect.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0018]]</b> is raised if the encryption type is not supported.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0019]]</b> is raised if the secret key is invalid.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0020]]</b> is raised if the block size is incorrect.<br/>
<b>[[XQuery Errors#Cryptographic Functions Errors|FOCX0021]]</b> is raised if the specified encryption algorithm is not supported.<br/>
|-
| valing='top' | '''Example'''
|'''Encrypts input data.'''
{| width='100%'|- valign="top"| width='120' | '''Signature'''|<pre>crypto:encrypt( $data as xs:anyAtomicType, $type as xs:string, $key as xs:anyAtomicType, $algorithm as xs:string) as xs:base64Binary</pre>|- valign="top"| '''Summary''Query'|Encrypts data with the specified key:* {{Code|$data}} must be a string or binary item.* {{Code|$type}} must be {{Code|symmetric}}.* {{Code|$key}} is the secret key which is used for both encryption and decryption of input data. It must be a string or binary item. Its length is fixed and depends on the chosen algorithm:8 bytes for {{Code|DES}}, 16 bytes for {{Code|AES}}.* {{Code|$algorithm}} must either be {{Code|DES}} or {{Code|AES}}. Default is {{Code|DES}}.|- valign="top"| '''Errors'''|{{Error|CX0016|#Errors}} padding problems arise.<pre classbr/>{{Error|CX0017|#Errors}} padding is incorrect.<br/>{{Error|CX0018|#Errors}} the encryption type is not supported.<br/>{{Error|CX0019|#Errors}} the secret key is invalid.<br/>{{Error|CX0020|#Errors}} the block size is incorrect.<br/>{{Error|CX0021|#Errors}} the specified encryption algorithm is not supported.<br/>|- valign="brushtop"| '''Example'''|Encrypt input data:<pre lang='xquery"'>crypto:encrypt('message', 'symmetric','keykeyke','DES')
</pre>
|}
==crypto:decrypt==
 {|width='100%'|-| valign='"top' "| width='90120' | '''SignaturesSignature'''|<code><bpre>crypto:decrypt</b>( $input data as xs:string()anyAtomicType, $decryption-type as xs:string(), $secret-key as xs:string()anyAtomicType, $cryptographic-algorithm as xs:string()) as xs:string()</codepre>|-| valign='"top' "| '''Summary'''|?Encrypts data with the specified key:* {{Code|$data}} must be a string or binary item.* {{Code|$type}} must be {{Code|symmetric}}.* {{Code|$key}} is the secret key which is used for both encryption and decryption of input data. It must be a string or binary item. Its length is fixed and depends on the chosen algorithm: 8 bytes for {{Code|DES}}, 16 bytes for {{Code|AES}}.* {{Code|$algorithm}} must either be {{Code|DES}} or {{Code|AES}}. Default is {{Code|-DES}}.| - valign='"top' "| '''Errors'''|{{Error|CX0016|#Errors}} padding problems arise.<br/>{{Error|CX0017|#Errors}} padding is incorrect.<br/>{{Error|CX0018|#Errors}} the encryption type is not supported.<bbr/>?{{Error|CX0019|#Errors}} the secret key is invalid.<br/>{{Error|CX0020|#Errors}} the block size is incorrect.<br/>{{Error|CX0021|#Errors}} the specified encryption algorithm is not supported.<br/b>|-| valingvalign='"top' "| '''Example'''|'''Decrypts Decrypt input data and returns the return original string.:'''Query:'''<pre lang='xquery'>let $encrypted := crypto:encrypt('message', 'symmetric', 'keykeyke', 'DES')return crypto:decrypt($encrypted, 'symmetric', 'keykeyke', 'DES')</pre> '''Result:'''<pre lang="xml">message</pre>
|}
 
=XML Signatures=
 
[https://www.w3.org/TR/xmldsig-core/ XML Signatures] are used to sign data. In our case, the data which is signed is an XQuery node. The following example shows the basic structure of an XML signature.
 
'''XML Signature'''
<pre lang="xml">
<Signature>
<SignedInfo>
<CanonicalizationMethod/>
<SignatureMethod/>
<Reference>
<Transforms/>
<DigestMethod/>
<DigestValue/>
</Reference>
<Reference/>
</SignedInfo>
<SignatureValue/>
<KeyInfo/>
<Object/>
</Signature>
</pre>
 
* '''SignedInfo''' contains or references the signed data and lists algorithm information
* '''Reference''' references the signed node
* '''Transforms''' contains transformations (i.e. XPath expressions) that are applied to the input node in order to sign a subset
* '''DigestValue''' holds digest value of the transformed references
* '''SignatureValue''' contains the Base64 encoded value of the encrypted digest of the {{Code|SignedInfo}} element
* '''KeyInfo''' provides information on the key that is used to validate the signature
* '''Object''' contains the node which is signed if the signature is of type {{Code|enveloping}}
 
'''Signature Types'''
 
Depending on the signature type, the {{Code|signature}} element is either placed as a child of the signed node ({{Code|enveloped}} type), or directly contains the signed node ({{Code|enveloping}} type). {{Code|Detached}} signatures are so far not supported.
 
'''Digital Certificate'''
 
The {{Code|generate-signature}} function allows to pass a {{Code|digital certificate}}. This certificate holds parameters that allow to access key information stored in a Java key store which is then used to sign the input document. Passing a {{Code|digital certificate}} simply helps re-using the same key pair to sign and validate data. The {{Code|digital certificate}} is passed as a node and has the following form:
 
<pre lang="xml">
<digital-certificate>
<keystore-type>JKS</keystore-type>
<keystore-password>...</keystore-password>
<key-alias>...</key-alias>
<private-key-password>...</private-key-password>
<keystore-uri>...</keystore-uri>
</digital-certificate>
</pre>
==crypto:generate-signature==
 {|width='100%'|-| valign='"top' "| width='90120' | '''SignaturesSignature'''|<code><bpre>crypto:generate-signature</b>( $input-doc as node(), $canonicalization-algorithm as xs:string(), $digest-algorithm as xs:string(), $signature-algorithm as xs:string(), $signature-namespace-prefix as xs:string(), $signature-type as xs:string, $ext1 as item(), $ext2 as node()) as node()</codepre>|- valign="top"| '''Summary'''|{{Code|$canonicalization}} must either be {{Code|inclusive-with-comments}}, {{Code|inclusive}}, {{Code|exclusive-with-comments}} or {{Code|exclusive}}. '''Default is {{Code|inclusive-with-comments}}'''.<br/>{{Code|$digest}} must be one of the following: {{Code|SHA1}}, {{Code|SHA256}} or {{Code|SHA512}}. '''Default is {{Code|SHA1}}'''.<codebr/>{{Code|$signature}} must either be {{Code|RSA_SHA1}} or {{Code|DSA_SHA1}}. '''Default is {{Code|RSA_SHA1}}'''.<bbr/>crypto:generate-signature{{Code|$prefix}} may be empty and prefixes the {{Code|Signature}} element accordingly.<br/b>({{Code|$input-doc nodetype}} is the signature type. It must either be {{Code|enveloped}} or {{Code|enveloping}} (detached signatures are not supported so far), . '''Default is {{Code|enveloped}}'''.<br/>{{Code|$canonicalization-algorithm as xs:string(), ext1}} may either be an {{Code|$digest-algorithm as xs:string(), xpath}} expression or a {{Code|$signature-algorithm as xs:string(), certificate}}.<br/>If {{Code|$signature-namespace-prefix ext2}} is specified as xs:string()well, {{Code|$signature-type as xs:string()ext1}} is an arbitrary XPath expression which specifies a subset of the document that is to be signed, and {{Code|$xpath-expression as xs:string()) as node()ext2}} is the digitial certificate used to sign the input document.<br/code>|- valign="top"| '''Errors'''|{{Error|CX0001|#Errors}} the canonicalization algorithm is not supported.<br/>{{Error|CX0002|#Errors}} the digest algorithm is not supported.<codebr/>{{Error|CX0003|#Errors}} the signature algorithm is not supported.<bbr/>crypto:generate{{Error|CX0004|#Errors}} the {{Code|$xpath-signatureexpression}} is invalid.<br/b>({{Error|CX0005|#Errors}} the root name of {{Code|$inputdigital-doc node(), $canonicalization-algorithm as xs:string(), $digest-algorithm as xs:string(), $signature-algorithm as xs:string(), $signature-namespace-prefix as xs:string(), $signature-type as xs:string(), $certificate}} is not 'digital-certificate as node()) as node().<br/>{{Error|CX0007|#Errors}} the key store is null.<br/code>{{Error|CX0012|#Errors}} the key cannot be found in the specified key store.<br/>{{Error|CX0023|#Errors}} the certificate alias is invalid.<codebr/>{{Error|CX0024|#Errors}} an invalid algorithm is specified.<bbr/>crypto:generate-signature{{Error|CX0025|#Errors}} an exception occurs while the signing the document.<br/>{{Error|CX0026|#Errors}} an exception occurs during key store initialization.<br/>{{Error|CX0027|#Errors}} an IO exception occurs.<br/b>($input-doc node(), $canonicalization-algorithm as xs:string(), $digest-algorithm as xs:string(), $signature-algorithm as xs:string(), ${{Error|CX0028|#Errors}} the signature-namespace-prefix as xs:string(), $signature-type as xs:string(), $xpath-expression as xs:string(), $digital-certificate as node()) as node()is not supported.<br/code>|-| valign='"top' "| '''SummaryExample'''|?Generate [https://www.w3.org/TR/xmldsig-core/ XML Signature]:|-| valign='top' | 'Query:''Errors'<pre lang='xquery'>|<b>?crypto:generate-signature(<a/b>|-| valing=, '', 'top' | , '', 'Example', '')</pre> |'''Generates an [Result:'''<pre lang="xml"><a> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-coresha1"/> <Reference URI=""> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>9hvH4qztnIYgYfJDRLnEMPJdoaY=</DigestValue> </Reference> </SignedInfo> <SignatureValue>Pn/Jr44WBcdARff2UVYEiwYW1563XdqnU87nusAIaHgzd+U3SrjVJhPFLDe0DJfxVtYzLFaznTYEP3ddeoFmyA==</SignatureValue> <KeyInfo> <KeyValue> <RSAKeyValue> <Modulus>rtvpFSbCIE2BJePlVYLIRIjXl0R7ESr2+D+JOVKn7AM7VZbcbRDPeqRbjSkEz1HWC/N067tjB3qH4/4PPT9bGQ==</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> </KeyValue> </KeyInfo> </ XML Signature].'''></a></pre>
|}
==crypto:validate-signature==
 {|width='100%'|-| valign='"top' "| width='90120' | '''SignaturesSignature'''|<code><bpre>crypto:validate-signature</b>( $input-doc as node()) as xs:boolean()</codepre>|-| valign='"top' "| '''Summary'''|?Checks if the given node contains a {{Code|Signature}} element and whether the signature is valid. In this case {{Code|true}} is returned. If the signature is invalid the function returns {{Code|false}}.|-| valign='"top' "| '''Errors'''|{{Error|CX0015|#Errors}} the signature element cannot be found.<bbr/>?{{Error|CX9994|#Errors}} an unspecified problem occurs during validation.<br/b>{{Error|-CX9996| valing='top' | '''Example'''|'''Validates #Errors}} an [http://wwwIO exception occurs during validation.w3.org<br/TR/xmldsig-core/ XML Signature].'''>
|}
 
=Errors=
 
{| class="wikitable" width="100%"
! width="110"|Code
|Description
|- valign="top"
|{{Code|CX0001}}
|The canonicalization algorithm is not supported.
|- valign="top"
|{{Code|CX0002}}
|The digest algorithm is not supported.
|- valign="top"
|{{Code|CX0003}}
|The signature algorithm is not supported.
|- valign="top"
|{{Code|CX0004}}
|The XPath expression is invalid.
|- valign="top"
|{{Code|CX0005}}
|The root element of argument $digital-certificate must have the name 'digital-certificate'.
|- valign="top"
|{{Code|CX0006}}
|The child element of argument $digital-certificate having position $position must have the name $child-element-name.
|- valign="top"
|{{Code|CX0007}}
|The keystore is null.
|- valign="top"
|{{Code|CX0008}}
|I/O error while reading keystore.
|- valign="top"
|{{Code|CX0009}}
|Permission denied to read keystore.
|- valign="top"
|{{Code|CX0010}}
|The keystore URL is invalid.
|- valign="top"
|{{Code|CX0011}}
|The keystore type is not supported.
|- valign="top"
|{{Code|CX0012}}
|Cannot find key for alias in given keystore.
|- valign="top"
|{{Code|CX0013}}
|The hashing algorithm is not supported.
|- valign="top"
|{{Code|CX0014}}
|The encoding method is not supported.
|- valign="top"
|{{Code|CX0015}}
|Cannot find Signature element.
|- valign="top"
|{{Code|CX0016}}
|No such padding.
|- valign="top"
|{{Code|CX0017}}
|Incorrect padding.
|- valign="top"
|{{Code|CX0018}}
|The encryption type is not supported.
|- valign="top"
|{{Code|CX0019}}
|The secret key is invalid.
|- valign="top"
|{{Code|CX0020}}
|Illegal block size.
|- valign="top"
|{{Code|CX0021}}
|The algorithm is not supported.
|- valign="top"
|{{Code|CX0023}}
|An invalid certificate alias is specified. Added to the official specification.
|- valign="top"
|{{Code|CX0024}}
|The algorithm is invalid. Added to the official specification.
|- valign="top"
|{{Code|CX0025}}
|Signature cannot be processed. Added to the official specification.
|- valign="top"
|{{Code|CX0026}}
|Keystore cannot be processed. Added to the official specification.
|- valign="top"
|{{Code|CX0027}}
|An I/O Exception occurred. Added to the official specification.
|- valign="top"
|{{Code|CX0028}}
|The specified signature type is not supported. Added to the official specification.
|}
 
=Changelog=
 
;Version 9.3
* Updated: {{Function||crypto:hmac}}, {{Function||crypto:encrypt}}, {{Function||crypto:decrypt}}: Function types revised.
 
;Version 8.6
* Updated: {{Function||crypto:hmac}}: The key can now be a string or a binary item.
 
The Module was introduced with Version 7.0.
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu