Chilkat load SSHKey without knowing the type - chilkat

I'm wondering if its possible to load a SSHKey via the Chilkat library without directly knowing the type. Currently I need to do something like this:
BOOL success = false;
if([privateKey FromOpenSshPublicKey: privateKeyString])
{
NSLog(#"key is FromOpenSshPublicKey");
success = true;
}
else if([privateKey FromPuttyPrivateKey: privateKeyString])
{
NSLog(#"key is FromPuttyPrivateKey");
success = true;
}
else if([privateKey FromRfc4716PublicKey: privateKeyString])
{
NSLog(#"key is FromRfc4716PublicKey");
success = true;
}
But it makes logging a bit difficult if I want to use something like LastErrorText.

The methods were originally written to load a key of a specific type. In actuality, all of the methods auto-recognize the type and will still load the key successfully. For example, you may call FromOpenSshPrivate key with a PuTTY private key, and it still works. (you can even pass PEM to it).
However... you do need to know if you have a public or private key. A call to FromPrivateKey will fail if you pass a public key to it. The reason is that the private parts of the key are simply not present, and if you wanted to load a private key it must be that you're doing something that requires a private key.
On the other hand, a public key is just a portion of the full private key. If you have a private key, by definition you also have the public key. (For example, an RSA public key is composed of the modulus and exponent, but an RSA private key contains modulus, exponent, plus other parts. If you have the private key, then you have the modulus and exponent and by definition you also have the public key.) Thus.. passing a private key to a method that loads a public key will still work. You're just passing more than what's necessary.

Related

SendTransactionAsync only works with public key

I am trying to call a function from my contract using Netherums "SendTransactionAsync", however, it only works when the source is a public key rather than a private key.
I am using Ganache private network to test my contract.
Error: One or more errors occurred. (sender account not recognized: eth_sendTransaction)
This is my Code
HexBigInteger gas = new HexBigInteger(new BigInteger(400000));
HexBigInteger value = new HexBigInteger(new BigInteger(0));
myContract.GetFunction("giveFruit").SendTransactionAsync("b6558007a470f0593a35be45926342e92942fa3d7d00fc357c104fcc428f0cee", gas, value, "apple");
The first parameter of the function is the address that is supposed to call this function and the last parameter
is an item passed to the contracts function?
The contract is working fine however when the code above doesn't work if I use the private key as shown, on the other hand, if I replace the private key with a public key it works just fine.
This doesn't make any sense, as you shouldn't be allowed to send transactions using public keys.

In ethers.js, can recoverPublicKey be used for signature verification?

In the bitcoin wiki they describe the algorithm used to verify a signature using ECDSA with Secp256k1. This algorithm has 3 inputs: signature, message hash and publicKey.
https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm
In ethers.js there is a a function with 2 inputs, hash and signature:
ethers.utils.recoverPublicKey( digest , signature )
https://docs.ethers.io/v5/api/utils/signing-key/
I'm tempted to think that to verify that the signature is correct would be simply to compare the publicKey with the result of recoverPublicKey:
publicKey === ethers.utils.recoverPublicKey( digest , signature )
However, I'm hesitant to make that assertion because according to this question: https://bitcoin.stackexchange.com/questions/107954/does-every-private-key-have-two-public-keys-ie-y-and-negated-y-secp256k1
A private key can have several associated publickeys, thus I'm worried that for the same input recoverPublicKey might return several different valid answers, making the equality invalid.
Also, in the
Standards for Efficient Cryptography 1 (SEC 1) (https://www.secg.org/sec1-v2.pdf), section 4.1.6. Public Key Recovery Operation, it says:
"Potentially, several candidate public keys can be recovered from a signature. At a small cost, the
signer can generate the ECDSA signature in such a way that only one of the candidate public keys
is viable"
It returns the public key that signed the message
ethers.utils.recoverPublicKey( digest , signature ) ⇒ string<
DataHexString< 65 > > Returns the uncompressed public key (i.e. the
first byte will be 0x04) of the private key that was used to sign
digest which gave the signature.
If you want to verify the public key then you have to fetch the public key from metamask to see if they are equal. metamask used to have eth_getEncryptionPublicKey method to get the public key but it is deprecated. I am not sure what method is used now:
window.ethereum.request({
method: 'eth_getEncryptionPublicKey',
params: [accounts],
});
ethers has this method
ethers.utils.verifyMessage( message , signature ) ⇒ string< Address >
Returns the address that signed message producing signature. The
signature may have a non-canonical v (i.e. does not need to be 27 or
28), in which case it will be normalized to compute the
recoveryParam which will then be used to compute the address; this
allows systems which use the v to encode additional data (such as
EIP-155) to be used since the v parameter is still completely
non-ambiguous.
I think this method will be easier to use

How to provide read and write to ColumnTransofrmer programatically in Hibernate?

I am using AES_ENCRYPT and AES_DECRYPT function of mysql which takes key as a parameter. However, I don't want to hardcode the key at application level, nor do I want to store it in application.properties file as I want to have the key in a different server. How can I achieve this ?
You can implement a custom MetadataContributor that can change the read/write mappings of a property programmatically.
public class MyMetadataContributor implements MetadataContributor {
public void contribute(InFlightMetadataCollector metadataCollector, IndexView jandexIndex) {
List<Selectable> selectables = metadataCollector.getEntityBindingMap().get("fqn.to.my.Entity")
.getProperty("myProperty")
.getValue()
.getSelectables();
((Column) selectables.get(0)).setCustomRead(...);
((Column) selectables.get(0)).setCustomWrite(...);
}
}

Botan: serialize ECDH private key

I created a new key pair using
Botan::EC_Group ecgroup("brainpool512r1");
Botan::ECDH_PrivateKey privKey(CBotanInitEx::RNG(), ecgroup);
(compared to RSA, that was fast!)
Trying to serialize it using PKCS#8, as per recommendations here:
https://botan.randombit.net/manual/pubkey.html#serializing-public-keys
datPubKey = Botan::X509::BER_encode(privKey);
txtPubKey = Botan::X509::PEM_encode(privKey);
datPrivKey = Botan::PKCS8::BER_encode(privKey, CBotanInitEx::RNG(), pwd);
txtPrivKey = Botan::PKCS8::PEM_encode(privKey, CBotanInitEx::RNG(), pwd);
I get an exception:
PK algo ECDH has no defined OIDs
even though botan initialization does pass this line:
add_oid(config, "1.3.36.3.3.2.8.1.1.13", "brainpool512r1");
How do I serialize a ECDH_PrivateKey?
RSA - your previous algorithm - is used for authentication / signing, so I'd assume ECDSA here. In that case you should use ECDSA_PrivateKey instead of ECDH_PrivateKey. ECDSA can be used for authentication and signing, while ECDH is used for key agreement.
Diffie-Hellman key agreement is usually performed without static key pairs (the E in ECDHE and DHE in the SSL/TLS ciphersuites stands for ephemeral). So there should be no reason to serialize / store private keys for key agreement.
In a sense you do need to think ahead and question yourself if you need serialization at all. You shouldn't serialize keys - especially private keys - if serialization isn't needed. Instead you could just pass on the object handle.

Boost asio ssl: password callback not called if private key passed with context::use_private_key

I'm writing a test unit that uses the boost asio ssl.
I'm using Boost 1.54 on Ubuntu 14.04 64 bit.
I plan to make the test self-sufficient and not rely on files to specify the private key, so I want to hard encode the key and its password in the test itself (they are just test key and password).
The code is below. For now it does nothing but I'm just trying to make the password callback work when the private key is specified:
std::string password_callback(
std::size_t max_length,
boost::asio::ssl::context::password_purpose purpose)
{
return "test";
}
TEST(StreamReader, sslStream)
{
std::string certificate = "-----BEGIN CERTIFICATE-----\n\
MIIFJjCCAw4CCQDQjrFrRcdRkjANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJT\n\
BLABLABLABLA";
std::string key = "-----BEGIN RSA PRIVATE KEY-----\n\
Proc-Type: 4,ENCRYPTED\n\
DEK-Info: DES-EDE3-CBC,06622C22CAB27AC2\n\
\n\
JMudxXy4ZxB733xh7QO4elsVCTzJZuWl9Go4ZMuWx0DZb2fYHqXynKZSf7UactSw\n\
vhKJnLPZaa5U+xOr9cdpSd3SwtQyNu6yaVQH3af2ILRwUsw9mQmI8yqIIF1Y6AgV\n\
BLABLABLABLA";
boost::asio::io_service io_service;
boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
ctx.set_password_callback(password_callback);
ctx.use_certificate(boost::asio::const_buffer(certificate.c_str(), certificate.size()), boost::asio::ssl::context::pem);
ctx.use_private_key(boost::asio::const_buffer(key.c_str(), key.size()), boost::asio::ssl::context::pem);
ctx.set_verify_mode(boost::asio::ssl::verify_peer);
}
When use_private_key is executed then the password callback is not called and I have to enter the password manually in the console. If I replace use_private_key with use_private_key_file then the callback is called.
I would expect password_callback to be called also when use_private_key is used.
Am I missing something?
This reflects a limitation of the underlying OpenSSL API:
Encyption applies to loading keys from file only:
The private keys loaded from file can be encrypted. In order to successfully load encrypted keys, a function returning the passphrase must have been supplied, see ssl_ctx_set_default_passwd_cb(3). (Certificate files might be encrypted as well from the technical point of view, it however does not make sense as the data in the certificate is considered public anyway.)
(from ssl_ctx_use_privatekey_file)
Consider using the raw key from inside the application. The raw key should be difficult to spot from looking at a binary. Of course you can scatter the key around in bits and encrypt them manually, but keep in mind a determined attacker can always figure it out anyways.
The rationale behind this could be that passphrase protected key files can be passed around safely, as long as the passphrase is not passed at the same time. As soon as you embed the key in the program that also contains the passphrase used to decrypt it, passing it around is inherently unsafe anyways.
UPDATE
In fact it should not be difficult to get the desired behaviour by patching Boost Asio: The use_private_key context member function ends up calling ::PEM_read_bio_PrivateKey which does support a password callback.
You could add it:
//evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0, 0, 0);
evp_private_key.p = ::PEM_read_bio_PrivateKey(bio.p, 0,
handle_->default_passwd_callback,
handle_->default_passwd_callback_userdata); // SEHE WAS HERE
to get the behaviour you want.
Be sure to ping the Asio developer/boost mailing lists whether they're interested in adding this as a feature.
I have to update this thread because I was in the same situation. It seems that support for this is now implemented:
https://github.com/boostorg/asio/blob/a2204b67f85cf63936a1daaacee830b6b69cec9f/include/boost/asio/ssl/impl/context.ipp#L845
So good news!