Encrypt and decrypt data using public/private key from node - corda

Is it possible to encrypt data using the node public key to store into a state and decrypt it using the node private key? i.e. Is it possible to access the node private key?

The node's public and private keys are an asymmetric key pair, and are meant to be used for signing.
For encryption and decryption, you should use symmetric key cryptography.

Related

Who gives the RSA private key to the opposite party

I have a very fundamental question on RSA keys. I understood the algorithm at high level. So, when I encrypt using a public key, it can only be (quickly) decrypted using a private key. So if I am communicating with you. How do you get the private key that you will use to decrypt my message? Wasn't this the original issue with DH algorithm as to how to share the keys beforehand.
As you identified, RSA uses a public and a private key. You never give out your private key, but your public key can be sent to others.
Say Alice is communicating with Bob, Alice will give Bob her public key which Bob uses to encrypt a message being sent to Alice. That encrypted message can only be decrypted using Alice's private key, so only Alice can decrypt it with her private key.
The same in the reverse. A message to Bob is encrypted with his public key, which can then only be decrypted using his private key.
The public key can only be used for encryption, and the private key can only be used for decryption.
You can read more about RSA here: https://brilliant.org/wiki/rsa-encryption/

Public / Private Key Cryptography for offline systems

Hi Crypto experts out there, are there any best practices around distributing an ecnrypted package to multiple end user systems, specially if the end system are offline ones? in context of assymetric crypto.
is it must to create unique pub/pvt key sets [ per end user system] and encrypt the same package many times uniquely with the pub keys, resulting in a specific package per end user system? how will this scale?
will it be a good practice to sign the original private key[ corresponding to pub keys used to encrypt the package] with senders private keys and then enrypt using end user systems pub keys and share it directly with end user? through trusted communication.
or, encrypt the pvt key with end user systems public key, sign with senders private key and re-encrypt[symmetric] this with the hash of certain string uniquely identifying a end user system? This hash should be programtically reproducible using system unique identifiers later during decryption processes. This way, to retreive the original private key to decrypt the package, it will require both a corresponding pub key[end user clients] as well as end user machine [the hash of string to be generated at runtime on end user system.] and senders public key to manage the authenticity?
Thank you for any feedback!
I am not an expert, but as I understand asymmetric encryption, you can generate a key pair in the distribution center.
The private key stays secret in the distribution center.
To each offline client you provide the public key (as a file).
Each client generates a secure password for symmetric encryption, and encrypts it using the public key.
The encrypted symmetric key is sent to the distribution center.
The distribution center should associate the encrypted symmetric password to the client that sent it.
At the time of encrypting the package for the specific client, the distribution center will decrypt the symmetric password using the private key, and use it to encrypt the package.
Then the package can be sent to the client, who will use it's own password to decrypt the package.

Signature with private key

My understanding is
for encryption : I use my recipient's PUBLIC KEY to encrypt my message. He will use his PRIVATE KEY to read my message (only HE can do this) => OK with that
for signing : I use my PRIVATE KEY (since no one has it, it proves my identity). But if my recipient use my PUBLIC KEY, every one could do the same and read my message ! Can anyone explain this ?
Then, I thought that what I should do is
I SIGN my message with my PRIVATE KEY => it proves my identity
I ENCRYPT the result of step 1 using my recipient's PUBLIC KEY => to avoid anyone reading it
HE decrypt with his PRIVATE KEY => only he can do this
HE check my identity with MY PUBLIC KEY
Is that correct ?
Your second guess is not bad.
Usually the way is the following for signing (not encryption):
Calculate a hash (e.g. SHA256) of your message that has to be signed.
Sign this hash (i.e. use your private key for RSA encryption)
That's it. Transfer the plain message and the signed hash to anyone. The message is not encrypted and therefore readable for all recipients. With the help of your public key everyone can decrypt the hash, calculate his or her own hash of your message and as long as both hashes (the self calculated and the signed and decrypted one) are equal, the signature is valid and the message has not beed changed after you have signed it.
In case your message has to be encrypted as well you usually do not use RSA, because it is to slow and to inflexible for larger messages (that means larger than the modulus of the private key, e.g. 2048 bit).
Use a symetric algorithm like AES CBC for the encryption of the message. The coincidentally generated key for encryption can be encrypted with the public key of your recipient and then be transfered.
To sum up signing and encryption using RSA with SHA256 (signature) and AES CBC (encryption):
1. Calculate a SHA256 hash H of your message M.
2. Sign H with your public key, i.e. encrypt H with your RSA private key. That is your signature S.
3. Generate a random key K.
4. Encrypt M with AES CBC to get the encrypted message M'.
5. Encrypt K with the public key of your recipient to get K'.
6. Send K', your signature S and M' to your recipient.
Only the recipient can undo all steps:
Decrypt K' with private key of the recipient to get K (RSA).
Decrypt M' with K (AES CBC) to get the message M.
Decrypt S with your public key (RSA) to get H.
Calculate a SHA256 hash of M.
Compare the calculated hash of step 4 with H (from step 3). If both are equal, the signature is verified successfully.

Symmetric Encryption with GPGME

According to the documentation the gpgme_op_encrypt method of GPGME is able to perform symmetric encryption tasks:
gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t cipher)
If recp is NULL, symmetric rather than public key encryption is
performed. Symmetrically encrypted cipher text can be deciphered with
gpgme_op_decrypt. Note that in this case the crypto backend needs to
retrieve a passphrase from the user. Symmetric encryption is currently
only supported for the OpenPGP crypto backend.
But where does the key used for the symmetric encryption come from? Is it somehow possible to fetch this key and transfer it to another device (where I would like to decrypt the text) ?
The session key for symmetric encryption is derived from a passphrase, which will be queried from the user through one of the pinentry methods. Specifically highlighting a part of the text you already quoted:
If recp is NULL, symmetric rather than public key encryption is performed. Symmetrically encrypted cipher text can be deciphered with gpgme_op_decrypt. Note that in this case the crypto backend needs to retrieve a passphrase from the user. Symmetric encryption is currently only supported for the OpenPGP crypto backend.
I'm not aware you can extract the session key through GPGME, but you don't really need to: all you need to know at the other end is the passphrase used, and the session key can be derived again. You could of course also reimplement the string-to-key-function used for OpenPGP.

What is a PGP Secret Key?

I am working on a C# app that encrypts/decrypts messages using PGP implemented by the Bouncy Castle (BC) library. I know PKI but the secret key in PGP throws me off a bit. I looked at the BC examples/source code and the PGP RFC but came away with more questions.
Is Secretkey == Session key?
Is Secretkey == Symmetric key?
Is Secretkey == private key (pub/priv key pairs)? At least the following seems to suggest that the secret key is a private key.
internal static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass)
The RFC says the secretkey contains, among others, information about the publickey or may be the public key itself (at least that's my reading).
Also, somewhere I read the Secretkey is basically a password encrypted privatekey.
When/why would I need a secret key in the PGP protocol? Signing or encrypting?
Thanks
Quoting RFC 4880, OpenPGP, 5.5.1.3. Secret-Key Packet:
A Secret-Key packet contains all the information that is found in a
Public-Key packet, including the public-key material, but also
includes the secret-key material after all the public-key fields.
and 11.2. Transferable Secret Keys:
[...] The format of a transferable
secret key is the same as a transferable public key except that
secret-key and secret-subkey packets are used instead of the public
key and public-subkey packets. Implementations SHOULD include self-
signatures on any user IDs and subkeys, [...]
With other words, the secret key contains the public/private key pair (eg., RSA), but should also contain user IDs and self-signatures. 12.1. Key Structures gives more details on how exported keys are constructed. A helpful tool for understanding the composition of OpenPGP packets are gpg --list-packets [file] or pgpdump [file], which dump the packet structure of their input.
In this case the secret key is a private key. The private key can be used for signing or decryption. Encryption and verification is performed using the public key of the other party. A secret key is nowadays mostly thought of to be a symmetric key, but it can also mean private, especially in older protocols.
There is a lot of this kind of confusion in cryptography, the best thing to do is to look at the context. For instance, if there is a public key, the key cannot be symmetric.

Resources