Skip to content

Instantly share code, notes, and snippets.

@ostinelli
Last active April 14, 2024 17:32
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save ostinelli/1770a93d5c01376728c9 to your computer and use it in GitHub Desktop.
Save ostinelli/1770a93d5c01376728c9 to your computer and use it in GitHub Desktop.
ECDSA usage from Ruby.
require 'openssl'
require 'base64'
# ===== \/ sign =====
# generate keys
key = OpenSSL::PKey::EC.new("secp256k1")
key.generate_key
public_key = key.public_key
public_key_hex = public_key.to_bn.to_s(16).downcase # public key in hex format
# sign a message
data = "My message to sign"
signature = key.dsa_sign_asn1(data)
signature_base64 = Base64.encode64(signature).gsub("\n", "")
# ===== \/ verify =====
# rebuild key
group = OpenSSL::PKey::EC::Group.new('secp256k1')
key = OpenSSL::PKey::EC.new(group)
# create point from hex key
public_key_bn = OpenSSL::BN.new(public_key_hex, 16)
public_key = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
key.public_key = public_key
# verify message
data = "My message to sign"
signature = Base64.decode64(signature_base64)
key.dsa_verify_asn1(data, signature)
@simlegate
Copy link

Maybe you should list the example how to generate public key by private key.
Here is the reference

@aniketdivekar
Copy link

Hi @ostinelli, @simlegate,
I needed some help.
I generated a key using key = OpenSSL::PKey::EC.new("secp256k1").generate_key
then I did private_key = key.private_key.to_s(16)
In another flow, I only have this private_key from above step. How can I generate back OpenSSL::PKey::EC instance using this private key?

Thanks in advance

@ignition42
Copy link

Hi @aniketdivekar, here you go!

key = OpenSSL::PKey::EC.new("secp256k1").generate_key
private_key = key.private_key.to_s(16)

# regenerate
group = OpenSSL::PKey::EC::Group.new('secp256k1')
new_key = OpenSSL::PKey::EC.new(group)

new_key.private_key = OpenSSL::BN.new(private_key, 16)
new_key.public_key = group.generator.mul(new_key.private_key)

@ykpoh
Copy link

ykpoh commented May 16, 2023

Hi, do you have version of this script for openssl version 3.0 & above? Because the keys are not mutable since 3.0 & above and will give this error.

15:30:48]: Error in your Fastfile at line 819
[15:30:48]:     817:	    # generate keys
[15:30:48]:     818:	    key = OpenSSL::PKey::EC.new("secp256k1")
[15:30:48]:  => 819:	    key.generate_key
[15:30:48]:     820:	    public_key = key.public_key
[15:30:48]:     821:	    public_key_hex = public_key.to_bn.to_s(16).downcase # public key in hex format
[15:30:48]: pkeys are immutable on OpenSSL 3.0

+------+----------------------+-------------+
|             fastlane summary              |
+------+----------------------+-------------+
| Step | Action               | Time (in s) |
+------+----------------------+-------------+
| 1    | default_platform     | 0           |
| 2    | xcodes               | 0           |
| 3    | ensure_env_vars      | 0           |
| 4    | set_info_plist_value | 0           |
+------+----------------------+-------------+

[15:30:48]: fastlane finished with errors

Looking for related GitHub issues on fastlane/fastlane...

Found no similar issues. To create a new issue, please visit:
https://github.com/fastlane/fastlane/issues/new
Run `fastlane env` to append the fastlane environment to your issue
Fastfile:819:in `generate_key!': \e[31m[!] pkeys are immutable on OpenSSL 3.0\e[0m (OpenSSL::PKey::PKeyError)
	from Fastfile:819:in `get_force_update_message'
	from Fastfile:252:in `block (2 levels) in parsing_binding'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane.rb:33:in `call'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:49:in `block in execute'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `chdir'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `execute'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:354:in `run'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:43:in `start'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/bin/fastlane:23:in `<top (required)>'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `load'
	from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `<main>'

@cpapidas
Copy link

If you are getting an error about immutability, use the following

key = OpenSSL::PKey::EC.generate("secp256k1")

instead of

key = OpenSSL::PKey::EC.new("secp256k1") # IT'S WRONG FOR OPENSSL 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment