CryptoKey
The CryptoKey
class in the 4D language encapsulates an asymmetric encryption key pair.
This class is available from the 4D
class store.
For a comprehensive overview of this class, please refer to the CryptoKey: encrypt, decrypt, sign, and verify! blog post.
Summary
4D.CryptoKey.new( settings : Object ) : 4D.CryptoKey creates a new 4D.CryptoKey object encapsulating an encryption key pair |
.curve : Text normalised curve name of the key |
.decrypt( message : Text ; options : Object ) : Object decrypts the message parameter using the private key |
.encrypt( message : Text ; options : Object ) : Text encrypts the message parameter using the public key |
.getPrivateKey() : Text returns the private key of the CryptoKey object |
.getPublicKey() : Text returns the public key of the CryptoKey object |
.sign (message : Text ; options : Object) : Text .sign (message : Blob ; options : Object) : Text signs the utf8 representation of a message string or Blob |
.size : Integer the size of the key in bits |
.type : Text name of the key type - "RSA", "ECDSA", "PEM" |
.verify( message : Text ; signature : Text ; options : Object) : Object *.verify**( message : Blob ; signature : Text ; options : Object) : Object verifies the base64 signature against the utf8 representation of message |
4D.CryptoKey.new()
History
Release | Changes |
---|---|
18 R4 | Added |
4D.CryptoKey.new( settings : Object ) : 4D.CryptoKey
Parameter | Type | Description | |
---|---|---|---|
settings | Object | -> | Settings to generate or load a key pair |
Result | 4D.CryptoKey | <- | Object encapsulating an encryption key pair |
The 4D.CryptoKey.new()
function creates a new 4D.CryptoKey
object encapsulating an encryption key pair, based upon the settings object parameter. It allows to generate a new RSA or ECDSA key, or to load an existing key pair from a PEM definition.
settings
Property | Type | Description |
---|---|---|
type | text | Defines the type of the key to create: |
curve | text | Name of ECDSA curve |
pem | text | PEM definition of an encryption key to load |
size | integer | Size of RSA key in bits |
CryptoKey
The returned CryptoKey
object encapsulates an encryption key pair. It is a shared object and can therefore be used by multiple 4D processes simultaneously.
Example 1
A message is signed by a private key and the signature is verified by the corresponding public key. The following code signs and verifies a simple message signature.
- Bob's side:
// Create the message
$message:="hello world"
Folder(fk desktop folder).file("message.txt").setText($message)
// Create a key
$type:=New object("type";"RSA")
$key:=4D.CryptoKey.new($type)
// Get the public key and save it
Folder(fk desktop folder).file("public.pem").setText($key.getPublicKey())
// Get signature as base64 and save it
Folder(fk desktop folder).file("signature").setText($key.sign($message;$type))
/*Bob sends the message, the public key and the signature to Alice*/
- Alice's side:
// Get message, public key & signature
$message:=Folder(fk desktop folder).file("message.txt").getText()
$publicKey:=Folder(fk desktop folder).file("public.pem").getText()
$signature:=Folder(fk desktop folder).file("signature").getText()
// Create a key
$type:=New object("type";"PEM";"pem";$publicKey)
$key:=4D.CryptoKey.new($type)
// Verify signature
If ($key.verify($message;$signature;$type).success)
// The signature is valid
End if
Example 2
The following sample code signs and verifies a message using a new ECDSA key pair, for example in order to make a ES256 JSON Web token.
// Generate a new ECDSA key pair
$key:=4D.CryptoKey.new(New object("type";"ECDSA";"curve";"prime256v1"))
// Get signature as base64
$message:="hello world"
$signature:=$key.sign($message;New object("hash";"SHA256"))
// Verify signature
$status:=$key.verify($message;$signature;New object("hash";"SHA256"))
ASSERT($status.success)
.curve
History
Release | Changes |
---|---|
18 R4 | Added |
.curve : Text
Defined only for ECDSA keys: the normalised curve name of the key. Usually "prime256v1" for ES256 (default), "secp384r1" for ES384, "secp521r1" for ES512.
.decrypt()
History
Release | Changes |
---|---|
18 R4 | Added |
.decrypt( message : Text ; options : Object ) : Object
Parameter | Type | Description | |
---|---|---|---|
message | Text | -> | Message string to be decoded using options.encodingEncrypted and decrypted. |
options | Object | -> | Decoding options |
Result | Object | <- | Status |
The .decrypt()
function decrypts the message parameter using the private key. The algorithm used depends on the type of the key.
The key must be a RSA key, the algorithm is RSA-OAEP (see RFC 3447).
options
Property | Type | Description |
---|---|---|
hash | text | Digest algorithm to use. For example: "SHA256", "SHA384", or "SHA512". |
encodingEncrypted | text | Encoding used to convert the message parameter into the binary representation to decrypt. Can be "Base64" or "Base64URL". Default is "Base64". |
encodingDecrypted | text | Encoding used to convert the binary decrypted message into the result string. Can be "UTF-8", "Base64", or "Base64URL". Default is "UTF-8". |
Result
The function returns a status object with success
property set to true
if the message could be successfully decrypted.
Property | Type | Description |
---|---|---|
success | boolean | True if the message has been successfully decrypted |
result | text | Message decrypted and decoded using the options.encodingDecrypted |
errors | collection | If success is false , may contain a collection of errors |
In case the message couldn't be decrypted because it was not encrypted with the same key or algorithm, the status
object being returned contains an error collection in status.errors
.
.encrypt()
History
Release | Changes |
---|---|
18 R4 | Added |
.encrypt( message : Text ; options : Object ) : Text
Parameter | Type | Description | |
---|---|---|---|
message | Text | -> | Message string to be encoded using options.encodingDecrypted and encrypted. |
options | Object | -> | Encoding options |
Result | Text | <- | Message encrypted and encoded using the options.encodingEncrypted |
The .encrypt()
function encrypts the message parameter using the public key. The algorithm used depends on the type of the key.
The key must be a RSA key, the algorithm is RSA-OAEP (see RFC 3447).
options
Property | Type | Description |
---|---|---|
hash | text | Digest algorithm to use. For example: "SHA256", "SHA384", or "SHA512". |
encodingEncrypted | text | Encoding used to convert the binary encrypted message into the result string. Can be "Base64", or "Base64URL". Default is "Base64". |
encodingDecrypted | text | Encoding used to convert the message parameter into the binary representation to encrypt. Can be "UTF-8", "Base64", or "Base64URL". Default is "UTF-8". |
Result
The returned value is an encrypted message.
.getPrivateKey()
History
Release | Changes |
---|---|
18 R4 | Added |
.getPrivateKey() : Text
Parameter | Type | Description | |
---|---|---|---|
Result | Text | <- | Private key in PEM format |
The .getPrivateKey()
function returns the private key of the CryptoKey
object in PEM format, or an empty string if none is available.
Result
The returned value is the private key.
.getPublicKey()
History
Release | Changes |
---|---|
18 R4 | Added |
.getPublicKey() : Text
Parameter | Type | Description | |
---|---|---|---|
Result | Text | <- | Public key in PEM format |
The .getPublicKey()
function returns the public key of the CryptoKey
object in PEM format, or an empty string if none is available.
Result
The returned value is the public key.
.pem
History
Release | Changes |
---|---|
18 R4 | Added |
.pem : Text
PEM definition of an encryption key to load. If the key is a private key, the RSA or ECDSA public key will be deduced from it.
.sign()
History
Release | Changes |
---|---|
20 R8 | Support of message as Blob |
18 R4 | Added |
.sign (message : Text ; options : Object) : Text
.sign (message : Blob ; options : Object) : Text
Parameter | Type | Description | |
---|---|---|---|
message | Text OR Blob | -> | Message to sign |
options | Object | -> | Signing options |
Result | Text | <- | Signature in Base64 or Base64URL representation, depending on "encoding" option |
The .sign()
function signs the utf8 representation of a message string or Blob using the CryptoKey
object keys and provided options. It returns its signature in base64 or base64URL format, depending on the value of the options.encoding
attribute you passed.
The CryptoKey
must contain a valid private key.
options
Property | Type | Description |
---|---|---|
hash | text | Digest algorithm to use. For example: "SHA256", "SHA384", or "SHA512". When used to produce a JWT, the hash size must match the PS@, ES@, RS@, or PS@ algorithm size |
encodingEncrypted | text | Encoding used to convert the binary encrypted message into the result string. Can be "Base64", or "Base64URL". Default is "Base64". |
pss | boolean | Use Probabilistic Signature Scheme (PSS). Ignored if the key is not an RSA key. Pass true when producing a JWT for PS@ algorithm |
encoding | text | Representation to be used for result signature. Possible values: "Base64" or "Base64URL". Default is "Base64". |
Result
The utf8 representation of the message.
.size
History
Release | Changes |
---|---|
18 R4 | Added |
.size : Integer
Defined only for RSA keys: the size of the key in bits. Typically 2048 (default).
.type
History
Release | Changes |
---|---|
18 R4 | Added |
.type : Text
Contains the name of the key type - "RSA", "ECDSA", "PEM" .
- "RSA": an RSA key pair, using
settings.size
as .size. - "ECDSA": an Elliptic Curve Digital Signature Algorithm key pair, using
settings.curve
as .curve. Note that ECDSA keys cannot be used for encryption but only for signature. - "PEM": a key pair definition in PEM format, using
settings.pem
as .pem.
.verify()
History
Release | Changes |
---|---|
20 R8 | Support of message as Blob |
18 R4 | Added |
.verify( message : Text ; signature : Text ; options : Object) : Object
*.verify**( message : Blob ; signature : Text ; options : Object) : Object
Parameter | Type | Description | |
---|---|---|---|
message | Text OR Blob | -> | Message that was used to produce the signature |
signature | Text | -> | Signature to verify, in Base64 or Base64URL representation, depending on options.encoding value |
options | Object | -> | Signing options |
Result | Object | <- | Status of the verification |
The .verify()
function verifies the base64 signature against the utf8 representation of message using the CryptoKey
object keys and provided options.
The CryptoKey
must contain a valid public key.
options
Property | Type | Description |
---|---|---|
hash | text | Digest algorithm to use. For example: "SHA256", "SHA384", or "SHA512". When used to produce a JWT, the hash size must match the PS@, ES@, RS@, or PS@ algorithm size |
pss | boolean | Use Probabilistic Signature Scheme (PSS). Ignored if the key is not an RSA key. Pass true when verifying a JWT for PS@ algorithm |
encoding | text | Representation of provided signature. Possible values are "Base64" or "Base64URL". Default is "Base64". |
Result
The function returns a status object with success
property set to true
if message
could be successfully verified (i.e. the signature matches).
In case the signature couldn't be verified because it was not signed with the same message, key or algorithm, the status
object being returned contains an error collection in status.errors
.
Property | Type | Description |
---|---|---|
success | boolean | True if the signature matches the message |
errors | collection | If success is false , may contain a collection of errors |