Document AES and new Crypto/CryptoKey functions.

This commit is contained in:
Fabio Alessandrelli 2020-06-18 12:39:56 +02:00
parent 8e3f9aa681
commit f055b86e65
3 changed files with 199 additions and 3 deletions

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AESContext" inherits="Reference" version="4.0">
<brief_description>
Interface to low level AES encryption features.
</brief_description>
<description>
This class provides access to AES encryption/decryption of raw data. Both AES-ECB and AES-CBC mode are supported.
[codeblock]
extends Node
var aes = AESContext.new()
func _ready():
var key = "My secret key!!!" # Key must be either 16 or 32 bytes.
var data = "My secret text!!" # Data size must be multiple of 16 bytes, apply padding if needed.
# Encrypt ECB
aes.start(AESContext.MODE_ECB_ENCRYPT, key.to_utf8())
var encrypted = aes.update(data.to_utf8())
aes.finish()
# Decrypt ECB
aes.start(AESContext.MODE_ECB_DECRYPT, key.to_utf8())
var decrypted = aes.update(encrypted)
aes.finish()
# Check ECB
assert(decrypted == data.to_utf8())
var iv = "My secret iv!!!!" # IV must be of exactly 16 bytes.
# Encrypt CBC
aes.start(AESContext.MODE_CBC_ENCRYPT, key.to_utf8(), iv.to_utf8())
encrypted = aes.update(data.to_utf8())
aes.finish()
# Decrypt CBC
aes.start(AESContext.MODE_CBC_DECRYPT, key.to_utf8(), iv.to_utf8())
decrypted = aes.update(encrypted)
aes.finish()
# Check CBC
assert(decrypted == data.to_utf8())
[/codeblock]
</description>
<tutorials>
</tutorials>
<methods>
<method name="finish">
<return type="void">
</return>
<description>
Close this AES context so it can be started again. See [method start].
</description>
</method>
<method name="get_iv_state">
<return type="PackedByteArray">
</return>
<description>
Get the current IV state for this context (IV gets updated when calling [method update]). You normally don't need this funciton.
Note: This function only makes sense when the context is started with [constant MODE_CBC_ENCRYPT] or [constant MODE_CBC_DECRYPT].
</description>
</method>
<method name="start">
<return type="int" enum="Error">
</return>
<argument index="0" name="mode" type="int" enum="AESContext.Mode">
</argument>
<argument index="1" name="key" type="PackedByteArray">
</argument>
<argument index="2" name="iv" type="PackedByteArray" default="PackedByteArray( )">
</argument>
<description>
Start the AES context in the given [code]mode[/code]. A [code]key[/code] of either 16 or 32 bytes must always be provided, while an [code]iv[/code] (initialization vector) of exactly 16 bytes, is only needed when [code]mode[/code] is either [constant MODE_CBC_ENCRYPT] or [constant MODE_CBC_DECRYPT].
</description>
</method>
<method name="update">
<return type="PackedByteArray">
</return>
<argument index="0" name="src" type="PackedByteArray">
</argument>
<description>
Run the desired operation for this AES context. Will return a [PackedByteArray] containing the result of encrypting (or decrypting) the given [code]src[/code]. See [method start] for mode of operation.
Note: The size of [code]src[/code] must be a multiple of 16. Apply some padding if needed.
</description>
</method>
</methods>
<constants>
<constant name="MODE_ECB_ENCRYPT" value="0" enum="Mode">
AES electronic codebook encryption mode.
</constant>
<constant name="MODE_ECB_DECRYPT" value="1" enum="Mode">
AES electronic codebook decryption mode.
</constant>
<constant name="MODE_CBC_ENCRYPT" value="2" enum="Mode">
AES cipher blocker chaining encryption mode.
</constant>
<constant name="MODE_CBC_DECRYPT" value="3" enum="Mode">
AES cipher blocker chaining decryption mode.
</constant>
<constant name="MODE_MAX" value="4" enum="Mode">
Maximum value for the mode enum.
</constant>
</constants>
</class>

View File

@ -5,7 +5,7 @@
</brief_description> </brief_description>
<description> <description>
The Crypto class allows you to access some more advanced cryptographic functionalities in Godot. The Crypto class allows you to access some more advanced cryptographic functionalities in Godot.
For now, this includes generating cryptographically secure random bytes, and RSA keys and self-signed X509 certificates generation. More functionalities are planned for future releases. For now, this includes generating cryptographically secure random bytes, RSA keys and self-signed X509 certificates generation, asymmetric key encryption/decryption, and signing/verification.
[codeblock] [codeblock]
extends Node extends Node
@ -21,12 +21,48 @@
# Save key and certificate in the user folder. # Save key and certificate in the user folder.
key.save("user://generated.key") key.save("user://generated.key")
cert.save("user://generated.crt") cert.save("user://generated.crt")
# Encryption
var data = "Some data"
var encrypted = crypto.encrypt(key, data.to_utf8())
# Decryption
var decrypted = crypto.decrypt(key, encrypted)
# Signing
var signature = crypto.sign(HashingContext.HASH_SHA256, data.sha256_buffer(), key)
# Verifying
var verified = crypto.verify(HashingContext.HASH_SHA256, data.sha256_buffer(), signature, key)
# Checks
assert(verified)
assert(data.to_utf8() == decrypted)
[/codeblock] [/codeblock]
[b]Note:[/b] Not available in HTML5 exports. [b]Note:[/b] Not available in HTML5 exports.
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
<methods> <methods>
<method name="decrypt">
<return type="PackedByteArray">
</return>
<argument index="0" name="key" type="CryptoKey">
</argument>
<argument index="1" name="ciphertext" type="PackedByteArray">
</argument>
<description>
Decrypt the given [code]ciphertext[/code] with the provided private [code]key[/code].
[b]Note[/b]: The maximum size of accepted ciphertext is limited by the key size.
</description>
</method>
<method name="encrypt">
<return type="PackedByteArray">
</return>
<argument index="0" name="key" type="CryptoKey">
</argument>
<argument index="1" name="plaintext" type="PackedByteArray">
</argument>
<description>
Encrypt the given [code]plaintext[/code] with the provided public [code]key[/code].
[b]Note[/b]: The maximum size of accepted plaintext is limited by the key size.
</description>
</method>
<method name="generate_random_bytes"> <method name="generate_random_bytes">
<return type="PackedByteArray"> <return type="PackedByteArray">
</return> </return>
@ -68,6 +104,34 @@
[/codeblock] [/codeblock]
</description> </description>
</method> </method>
<method name="sign">
<return type="PackedByteArray">
</return>
<argument index="0" name="hash_type" type="int" enum="HashingContext.HashType">
</argument>
<argument index="1" name="hash" type="PackedByteArray">
</argument>
<argument index="2" name="key" type="CryptoKey">
</argument>
<description>
Sign a given [code]hash[/code] of type [code]hash_type[/code] with the provided private [code]key[/code].
</description>
</method>
<method name="verify">
<return type="bool">
</return>
<argument index="0" name="hash_type" type="int" enum="HashingContext.HashType">
</argument>
<argument index="1" name="hash" type="PackedByteArray">
</argument>
<argument index="2" name="signature" type="PackedByteArray">
</argument>
<argument index="3" name="key" type="CryptoKey">
</argument>
<description>
Verify that a given [code]signature[/code] for [code]hash[/code] of type [code]hash_type[/code] against the provided public [code]key[/code].
</description>
</method>
</methods> </methods>
<constants> <constants>
</constants> </constants>

View File

@ -11,13 +11,34 @@
<tutorials> <tutorials>
</tutorials> </tutorials>
<methods> <methods>
<method name="is_public_only" qualifiers="const">
<return type="bool">
</return>
<description>
Return [code]true[/code] if this CryptoKey only has the public part, and not the private one.
</description>
</method>
<method name="load"> <method name="load">
<return type="int" enum="Error"> <return type="int" enum="Error">
</return> </return>
<argument index="0" name="path" type="String"> <argument index="0" name="path" type="String">
</argument> </argument>
<argument index="1" name="public_only" type="bool" default="false">
</argument>
<description> <description>
Loads a key from [code]path[/code] ("*.key" file). Loads a key from [code]path[/code]. If [code]public_only[/code] is [code]true[/code], only the public key will be loaded.
[b]Note[/b]: [code]path[/code] should should be a "*.pub" file if [code]public_only[/code] is [code]true[/code], a "*.key" file otherwise.
</description>
</method>
<method name="load_from_string">
<return type="int" enum="Error">
</return>
<argument index="0" name="string_key" type="String">
</argument>
<argument index="1" name="public_only" type="bool" default="false">
</argument>
<description>
Loads a key from the given [code]string[/code]. If [code]public_only[/code] is [code]true[/code], only the public key will be loaded.
</description> </description>
</method> </method>
<method name="save"> <method name="save">
@ -25,8 +46,20 @@
</return> </return>
<argument index="0" name="path" type="String"> <argument index="0" name="path" type="String">
</argument> </argument>
<argument index="1" name="public_only" type="bool" default="false">
</argument>
<description> <description>
Saves a key to the given [code]path[/code] (should be a "*.key" file). Saves a key to the given [code]path[/code]. If [code]public_only[/code] is [code]true[/code], only the public key will be saved.
[b]Note[/b]: [code]path[/code] should should be a "*.pub" file if [code]public_only[/code] is [code]true[/code], a "*.key" file otherwise.
</description>
</method>
<method name="save_to_string">
<return type="String">
</return>
<argument index="0" name="public_only" type="bool" default="false">
</argument>
<description>
Returns a string containing the key in PEM format. If [code]public_only[/code] is [code]true[/code], only the public key will be included.
</description> </description>
</method> </method>
</methods> </methods>