Get elliptic curve public key from private key using Ruby OpenSSL - ruby

I'm playing around with Elliptic Curves using the Ruby 2.5.x OpenSSL library. I can easily generate a private and public key pair using
curve = OpenSSL::PKey::EC.new('secp256k1')
curve.generate_key
But given a private key I want to regenerate the public key.
I know OpenSSL can do it because the command line allows you to do it, and also the Ruby Bitcoin project does it. But the Ruby Bitcoin project has its own interface to OpenSSL using FFI rather than the one provided by Ruby.
Does Ruby 2.5.x openssl library not expose enough of the OpenSSL interfaces to be able to generate an elliptic curve public key from a private key, or that it can but it's not documented?

In case someone interested to get public key in pem format too :)
example_key = OpenSSL::PKey::EC.new('secp256k1').generate_key
puts example_key.to_pem
pkey = OpenSSL::PKey::EC.new(example_key.public_key.group)
pkey.public_key = example_key.public_key
puts pkey.to_pem

The Ruby OpenSSL bindings don’t allow you to directly get the public key from a PKey::EC object as far as I can tell, but they do expose enough to do the calculation yourself, which is straightforward.
Given a private key as an OpenSSL:BN object, which for the example we can generate like this:
example_key = OpenSSL::PKey::EC.new('secp256k1').generate_key
private_key = example_key.private_key
We can calculate the public key by multiplying the group base point (i.e. the generator) by the private key:
group = OpenSSL::PKey::EC::Group.new('secp256k1')
public_key = group.generator.mul(private_key)
The public key is an OpenSSL::PKey::EC::Point. You can compare with the original to see that is the same:
puts example_key.public_key == public_key # => true

Related

How to offline sign a Tron transaction in Ruby?

I'm trying to offline sign a Tron transaction in Ruby.
TronGrid has an endpoint to sign transactions, but they require to send them the account private key in order to do it, which feels a potential risk, so I'd like to sign the transaction locally in order to avoid having the private key value leaving the server.
In the specific I'm trying to convert this Javascript method in Ruby: https://github.com/tronprotocol/tronweb/blob/master/src/utils/crypto.js#L218
I've been trying using both OpenSSL and a gem to do this without much success.
This is what I've got so far:
bn = OpenSSL::BN.new(hex_private_key, 16)
ec = OpenSSL::PKey::EC.new('secp256k1')
ec.private_key = bn
ec.dsa_sign_asn1(transaction_id).unpack1('H*')
and
bn = OpenSSL::BN.new(hex_private_key, 16)
private_key = EC::PrivateKey.new(bn.to_i)
signature = private_key.sign(transaction_id)
The latter gives me the r and s that is then used in the javascript function (even though they wouldn't match what I'd get in JS), and I'm not sure where I could get that recoveryParam.
And the former doesn't return me the signature I was expecting.
I'm kinda lost on how to find out a way to sign those transactions.
Did you find out how to do it?
In the example takes raw_data_hex:
private static byte[] signTransaction2Byte(byte[] transaction, byte[] privateKey)
throws InvalidProtocolBufferException {
ECKey ecKey = ECKey.fromPrivate(privateKey);
Transaction transaction1 = Transaction.parseFrom(transaction);
byte[] rawdata = transaction1.getRawData().toByteArray();
byte[] hash = Sha256Sm3Hash.hash(rawdata);
byte[] sign = ecKey.sign(hash).toByteArray();
return transaction1.toBuilder().addSignature(ByteString.copyFrom(sign)).build().toByteArray();
}`
`Sha256Sm3Hash.hash` returns `sha256` or `sm3` depends on private key.

BCrypt in Spring gives different hash then online tools

I'm using BCrypt in Spring and it's giving me different hashes then some online tools are using like https://bcrypt-generator.com/
Any ideas why?
I've tried setting the strength to 12 in Spring and on the bcrypt-generator.com setting rounds to 12 and it did not work.
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(new BCryptPasswordEncoder(12));
provider.setUserDetailsService(bettingBotUserDetailsService);
For the raw password "admin" I get these results:
bcrypt-generator.com with 12 rounds:
$2y$12$15h6Idq/TwfcuJu6H1VXie/ao7P4AKlLgIrC5yxbwlEUdJjx9Sl5S
Spring (captured from debug mode):
$2a$10$ED5wQChpxzagbvhlqEqD2.iIdIKv9ddvJcX0WKrQzSOckgc3RHFLW
BCrypt generates the different salt for the same Input. Bcrypt Algorithm
BCrypt returns a different hash each time because it incorporates a different random value into the hash. This is known as a "salt". It prevents people from attacking your hashed passwords with a "rainbow table", a pre-generated table mapping password hashes back to their passwords. The salt means that instead of there being one hash for a password, there's 2^16 of them.
We can check the hashed with normal string as follow
Boolean isMatch = passwordEncoder().matches(currentPassword,dbPassword);
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

Why is an OpenSSL::PKey::RSA key both private and public?

I'm learning about the OpenSSL ruby module.
Shown below is a pry session where I generate a key using the RSA asymmetric public key algorithm. I also call the #private? and #public? instance methods:
[1] pry(main)> require 'openssl'
=> true
[2] pry(main)> alices_key = OpenSSL::PKey::RSA.new 2048
=> #<OpenSSL::PKey::RSA:0x007fc0751cb028>
[3] pry(main)> alices_key.public?
=> true
[4] pry(main)> alices_key.private?
=> true
Why is the #<OpenSSL::PKey::RSA:0x007fc0751cb028> object both public and private?
Usually the data structure of the private key also contains the public exponent. They are generated in the same key pair generation in the first place.
It is easy to store them together as the public key is the modulus + the public exponent (usually the value 0x10001, the fourth prime of Fermat). The modulus of course is also part of the private key, so that doesn't need to be duplicated.
The public key may also be used to protect against some side channel attacks although that's not such a big issue in software.
It depends on the software if the private key can also be used as a public key and if the public exponent is stored with the private key. But it is quite common, e.g. a private key object in PKCS#11 (used for software, smart cards and HSM's) also contains the public exponent. On the other hand Java has separate PrivateKey and PublicKey classes where the PrivateKey doesn't contain the public exponent (or it doesn't expose it through the public API anyway).
In the end we cannot answer the question without consulting the original OpenSSL guys (Mr. Young and Mr Hudson, I suppose) but there are good reasons for storing the public exponent as well, and as the public key is public it doesn't hurt either.

How to get keys from hash - ruby c extension

I am looking for a function which can get me all the keys from hash or I can loop through the hash to retrieve single key at a time.
Currently I am hardcoding key
VALUE option = rb_hash_aref(options, rb_str_new2("some_key"));
You can iterate over the key/value pairs with a callback function using rb_hash_foreach (blog post w/an example):
void rb_hash_foreach(VALUE, int (*)(ANYARGS), VALUE);
There is an rb_hash_keys in MRI, but it's not in any header files it seems, so using it may be risky.
You could always make a call to the Ruby method itself:
VALUE keys = rb_funcall(hash, rb_intern("keys"), 0)

What cryptographically secure options are there for creating random numbers in WinRT?

Ordinarily I'd do something like this:
byte[] randomBytes = new byte[bytes];
string randomString = Convert.ToBase64String(new RNGCryptoServiceProvider().GetBytes(randomBytes));
However there's no RNGCryptoServiceProvider available.
Are there any secure random alternatives available?
Thanks,
I managed to find an equivalent.
using Windows.Security.Cryptography;
IBuffer randomBuffer = CryptographicBuffer.GenerateRandom(PASSWORD_SALT_LENGTH);
string randomString = CryptographicBuffer.EncodeToBase64String(randomBuffer)
I hope this is of use to someone else.

Resources