Changes

Jump to navigation Jump to search
11,548 bytes added ,  12:32, 8 May 2024
no edit summary
This [[Module Library|XQuery Module]] 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 decryptionAll functions in this module are assigned to the <code><nowiki>http://expath.org/ns/crypto</nowiki></code> namespace, which is statically bound to the {{Code|crypto}} prefix.<br/>All errors are assigned to the <code><nowiki>http://expath.org/ns/error</nowiki></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(), algorithm as xs:string()) as xs:string()</code><br/><code><b>crypto:hmac</b>($message as xs:string()anyAtomicType, $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/>$encoding }} 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|$algorithm }} 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|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>sha384. Default is {{Code|base64}}.|- valign="top"| '''Errors'''|{{Error|CX0013|#Errors}} the specified hashing algorithm is not supported.<br/code>, {{Error|CX0014|#Errors}} the specified encoding method is not supported.<codebr/>sha512{{Error|CX0019|#Errors}} the specified secret key is invalid.<br/code>.|-valign="top"| valign'''Example'''|Return message authentication code (MAC) for a given string:'''Query:'''<pre lang='topxquery'>crypto:hmac('message', 'secretkey', 'md5', 'hex' | )</pre> '''ErrorsResult:'''|<bpre lang="xml">?34D1E3818B347252A75A4F6D747B21C2</bpre>
|}
 
=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|$ext1}} may either be an {{Code|$xpath}} expression or a {{Code|$certificate}}.<br/>If {{Code|$ext2}} is specified as well, {{Code|$ext1}} is an arbitrary XPath expression which specifies a subset of the document that is to be signed, and {{Code|$ext2}} is the digitial certificate used to sign the input document.<br/>|- valign="top"| '''Errors'''|{{Error|CX0001|#Errors}} the canonicalization-algorithm as xs:string(), $is not supported.<br/>{{Error|CX0002|#Errors}} the digest-algorithm as xs:string(), $is not supported.<br/>{{Error|CX0003|#Errors}} the signature-algorithm as xs:string(), is not supported.<br/>{{Error|CX0004|#Errors}} the {{Code|$signaturexpath-namespace-prefix as xs:string(), expression}} is invalid.<br/>{{Error|CX0005|#Errors}} the root name of {{Code|$signaturedigital-type as xs:string(), $xpathcertificate}} is not 'digital-expression as xs:string()) as node()certificate.<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/>{{Error|CX0024|#Errors}} an invalid algorithm is specified.<br/>{{Error|CX0025|#Errors}} an exception occurs while the signing the document.<br/>{{Error|CX0026|#Errors}} an exception occurs during key store initialization.<br/code>{{Error|CX0027|#Errors}} an IO exception occurs.<br/>{{Error|CX0028|#Errors}} the signature type is not supported.<codebr/>|- valign="top"| '''Example'''|Generate [https://www.w3.org/TR/xmldsig-core/ XML Signature]: '''Query:'''<bpre lang='xquery'>crypto:generate-signature(<a/b>($input-doc node(, '', '', '', '', ''), $canonicalization-algorithm as xs</pre> '''Result:'''<pre lang="xml"><a> <Signature xmlns="http:string(), $digest-algorithm as xs//www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http:string(), $signature//www.w3.org/TR/2001/REC-algorithm as xs:string(), $signaturexml-namespacec14n-prefix as xs20010315#WithComments"/> <SignatureMethod Algorithm="http:string(), $signature//www.w3.org/2000/09/xmldsig#rsa-type as xssha1"/> <Reference URI=""> <Transforms> <Transform Algorithm="http:string(), $digital//www.w3.org/2000/09/xmldsig#enveloped-certificate as node()) as node()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> </codeKeyInfo> <br/Signature><code/a><b/pre>|} ==crypto:generatevalidate-signature== {| width='100%'|- valign="top"| width='120' | '''Signature'''|</bpre>($input-doc node(), $canonicalization-algorithm as xscrypto:string(), $digestvalidate-algorithm as xs:string(), $signature-algorithm as xs:string(), $signatureinput-namespace-prefix doc as xs:stringnode(), $signature-type as xs:string(), $xpath-expression as xs:string(), $digital-certificate as node()) as node()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.
|}
 
=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