extends Control
@onready var msg: TextEdit = $MarginContainer/HBoxContainer/VBoxContainer2/Message
@onready var sig: TextEdit = $MarginContainer/HBoxContainer/VBoxContainer2/Signature
const private_file = "private.rsa"
const public_file = "public.rsa"
var rsa = Crypto.new()
var privateKey: CryptoKey
var publicKey: CryptoKey
func _on_btn_generate_pressed() -> void:
var cryptoKey := rsa.generate_rsa(2048)
var err: Error
err = cryptoKey.save(private_file)
if err != 0:
msg.text = "Failed to save private key file. Error %s" % err
return
# The second parameter to CryptoKey.save indicates it should only save the
# public portion of the key. This can be verified by reading the resulting
# output file in a text editor.
err = cryptoKey.save(public_file, true)
if err != 0:
msg.text = "Failed to save public key file. Error %s" % err
return
msg.text = "Generated new keypair. You may now load either key."
func _on_btn_unload_pressed() -> void:
privateKey = null
publicKey = null
msg.text = "Unloaded all keys"
func _on_btn_load_private_pressed() -> void:
publicKey = null
privateKey = CryptoKey.new()
var err := privateKey.load(private_file)
if err != null and err != 0:
msg.text = "Failed to load private key. Error %s. Try generating a new pair." % err
else:
msg.text = "Successfully loaded private key"
func _on_btn_load_public_pressed() -> void:
privateKey = null
publicKey = CryptoKey.new()
# As with the call to CryptoKey.save when we generate the keypair, the second
# argument here being set to true indicates that we are only expecting to load
# the PUBLIC portion of the key. Attempting to load the public file without
# passing true in the second parameter will result in an error, since the file
# only contains the public key.
var err := publicKey.load(public_file, true)
if err != 0:
msg.text = "Failed to load public key. Error %s. Try generating a new pair." % err
else:
msg.text = "Successfully loaded public key"
func _on_btn_sign_pressed() -> void:
if privateKey == null:
sig.text = "No private key loaded. Please generate and load private key before signing."
return
var digest := get_message_digest()
var signature := rsa.sign(HashingContext.HASH_SHA256, digest, privateKey)
sig.text = signature.hex_encode()
# get_message_digest implements SHA256 hashing on a variable-sized text buffer.
# This is a required step in order to sign or verify using RSA. For a brief
# overview of why, see https://crypto.stackexchange.com/questions/12768/why-hash-the-message-before-signing-it-with-rsa
func get_message_digest() -> PackedByteArray:
var clearText := msg.text
if clearText.length() == 0 or clearText == null:
push_error("No cleartext present!")
return PackedByteArray()
var bytes := clearText.to_ascii_buffer()
var buffer := PackedByteArray()
buffer.resize(1024)
buffer.fill(0)
var ctx := HashingContext.new()
ctx.start(HashingContext.HASH_SHA256)
var partial := false
for i in range(bytes.size()):
buffer[i % 1024] = bytes[i]
partial = true
if i % 1024 == 0 and i != 0:
partial = false
ctx.update(buffer)
buffer.fill(0)
if partial:
ctx.update(buffer)
return ctx.finish()
func _on_btn_verify_pressed() -> void:
if publicKey == null:
sig.text = "No public key loaded. Please generate and load public key before verifying."
return
var clearText := msg.text
var signature := sig.text
if clearText.length() == 0 or signature.length() == 0:
msg.text = "Please enter a message and its signature before attempting verification."
return
var digest := get_message_digest()
var sigBytes := signature.hex_decode()
var valid = rsa.verify(HashingContext.HASH_SHA256, digest, sigBytes, publicKey)
if valid:
sig.text = "Signature verified!"
else:
sig.text = "Signature not valid!"
func _on_btn_exit_pressed() -> void:
get_tree().quit()
https://github.com/kintar/godot_RSA_signature_example/blob/main/main.gd
Comments “Dnes ma zaujalo na sieti RSA signature example. Aby mi to nezmizlo, spravím si malú zálohu:”