Changes

Jump to navigation Jump to search
10,511 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==
 {|width='100%'|-| valign='"top' "| width='90120' | '''SignaturesSignature'''|<code><bpre>crypto:hmac</b>( $message data as xs:string()anyAtomicType, $secret-key as xs:string()anyAtomicType, 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()</codepre>|-| valign='"top' "| '''Summary'''|Creates a message an authentication code for the specified {{Code|$data}} via a cryptographic hash function and a secret :* {{Code|$key. <br/><code>$encoding</code> }} must either not 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>* {{Code|$algorithm</code> }} describes the hash algorithm which is used for encryption. Currently supported are <code>{{Code|md5</code>}}, <code>{{Code|sha1</code>}}, <code>{{Code|sha256</code>}}, <code>{{Code|sha384</code>}}, <code>{{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'''|<b>[[XQuery Errors{{Error|CX0013|#Cryptographic Functions Errors|FOCX0013]]</b> is raised if }} the specified hashing algorithm is not supported.<br/><b>[[XQuery Errors{{Error|CX0014|#Cryptographic Functions Errors|FOCX0014]]</b> is raised if }} the specified encoding method is not supported.<br/><b>[[XQuery Errors{{Error|CX0019|#Cryptographic Functions Errors|FOCX0019]]</b> is raised if }} the specified secret key is invalid.<br/>|- valign="top"| '''Example'''|Return message authentication code (MAC) for a given string:'''Query:'''<pre lang='xquery'>crypto:hmac('message', 'secretkey', 'md5', 'hex')</pre> '''Result:'''<pre lang="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==
 {|width='100%'|-| valign='"top' "| width='90120' | '''SignaturesSignature'''|<code><bpre>crypto:encrypt</b>( $input data as xs:string()anyAtomicType, $encryption-type as xs:string(), $secret-key as xs:string()anyAtomicType, $cryptographic-algorithm as xs:string()) as xs:string()base64Binary</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.<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='"top' "| '''ErrorsExample'''|Encrypt input data:<bpre lang='xquery'>?crypto:encrypt('message', 'symmetric', 'keykeyke', 'DES')</bpre>
|}
==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.<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="top"| '''Example''top' | Decrypt input data and return original string:'''Query:'''<pre lang='xquery'>let $encrypted := crypto:encrypt('message', 'symmetric', 'Errorskeykeyke', 'DES')return crypto:decrypt($encrypted, 'symmetric', 'keykeyke', 'DES')</pre> '''Result:'''|<bpre lang="xml">?message</bpre>
|}
 
=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/>{{Error|CX0012|#Errors}} the key cannot be found in the specified key store.<br/>{{Error|CX0023|#Errors}} the certificate alias is invalid.<br/code>{{Error|CX0024|#Errors}} an invalid algorithm is specified.<br/>{{Error|CX0025|#Errors}} an exception occurs while the signing the document.<codebr/>{{Error|CX0026|#Errors}} an exception occurs during key store initialization.<bbr/>crypto:generate-signature{{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(), $signature-namespace-prefix as xs:string(), ${{Error|CX0028|#Errors}} the 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]: |-'''Query:'''| valign<pre lang='topxquery'>crypto:generate-signature(<a/>, '', '', '', '', '' | )</pre> '''ErrorsResult:'''|<bpre 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-sha1"/> <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> </Signature></a>?</bpre>
|}
==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.<br/>{{Error|CX9994|#Errors}} an unspecified problem occurs during validation.<bbr/>?{{Error|CX9996|#Errors}} an IO exception occurs during validation.<br/b>|} =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.
|}
==Examples=Changelog=
'''Example 1;Version 9.3* Updated: {{Function||crypto:hmac}}, {{Function||crypto:encrypt}}, {{Function||crypto:decrypt}}: Returning the message authentication code (MAC) for a messageFunction types revised.'''
'''Query:''';Version 8.6<pre class="brush* Updated:xquery">{{Function||crypto:hmac('message','secretkey','md5','base64')}}: The key can now be a string or a binary item. </pre>The Module was introduced with Version 7.0.
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu