I'm curious about the Bouncy Castle API process for handling multiple public keys to encrypt data. For example, if i have 3 different clients that would like me to encrypt data and send to them using their public key for encryption, if i label each clients public key respectively - how does bouncy castle determine that client 1 should be encrypted with public key 1 and not public key 3 (which would be the public key for client 3)?
it would seem from a decrpytion standpoint, that publicKeyEncryptedData has a keyID tag attached with it that can be used to look up the corresponding private key, but i dont understand how it chooses the correct key to encrypt with.
It doesn't. You have to specify all recipients (i.e. certificates to use for encryption). When you are doing encryption using PKCS#7 the process is:
Generate random symmetric key (i.e. AES256)
encrypt data with symmetric key
encrypt symmetric key with public key of the recipient (if X recipients should be able to decrypt then encrypt the symmetric key X-times)
put it all together in PKCS#7 (encrypted symmetric key is put in a structure with some identification of the recipient. Usually it is serial number and issuer DN of the certificate which was used for encryption of symmetric key)
Decryption process is:
find recipient able to decrypt the message. PKCS#7 contains serial numbers and issuer DNs of all recipients who should be able to decrypt. Now look in crypto store for a certificate with serial number and issuer DN that has a corresponding private key. It does not matter which private key will be used if you have all recipients private keys in crypto store.
use private key to decrypt symmetric key used in the encryption process
use symmetric key to decrypt data
Related
I have a .p12 file generated by the Java keytool and need to read all of the Secret Key (AES 256) entries from it so that I can use it to encrypt stuff in my C# app.
I have looked at Bouncy Castle and that only seems to handle Asymmetric keys and X509 certificates.
Can the C# OpenSSL wrapper do this?
.p12 contains the X509Certificate incl. (optionally) the private asymmetric key.
As far as I know, there is no Symmectric (AES) Key in there, but only asymmetric keys.
If you want to use it for S/MIME, it uses a random symmetric kes (AES, 3DES, ...) and enrypts this key with the asymmetric key of the user(s) you send the email to and of course your own.
Have a look at MimeKit and/or MailKit for S/MIME.
If you just want to encrypt some stuff:
Just generate a random AES Key (just some random bytes) and put all of your stuff in some kind of container which includes the asymmetrically encrypted AES key. You could use the ApplicationPKCS from MimeKit (imitating S/MIME) or do something on your own. Just make sure, to identify the certificate you have use to encrypt the symmetric key.
I am using a Token based authentication. My web server would generate and encrypt the token. I want the client to decrypt the token to read certain payload information.
What algorithm I should use to achieve this?
In my understanding if I use RSA, I can decrypt in c# using private key whereas the encryption has to happen from other hand so this doesn't fit-in my scenario. Is there any other asymmetric algorithm or ways to achieve this?
Server encrypt - private key.
Client decrypt - public key.
Is there any other asymmetric algorithm or ways to achieve this please suggest.
I want to correct your understanding of asymmetric encryption. Asymmetric encryption allows anyone with the public key to send a secret message to anyone with the private key. Since the public key is public, asymmetric encryption allows many possible senders to send private messages to a few special recipients.
My web server would generate and encrypt the token. I want the client to decrypt the token to read certain payload information.
In that case, with the server sending a secret message to the client, if you are using asymmetric encryption, then the server will encrypt with the public key, and the client will decrypt with the private key.
Server encrypt - private key. Client decrypt - public key.
That is not correct. In asymmetric cryptography, the public key does the encryption and the private key does the decryption.
What you might be thinking about is a digitally signed message. In that case, the sender signs the message with the private key and the receiver verifies the signature with the public key. Digitally signed messages are not secret, though, whereas encrypted messages are secret.
Is there any other asymmetric algorithm or ways to achieve this please suggest.
Since your use case is not entirely clear, I will stop the answer there, and leave it at correcting your understanding of asymmetric encryption. It might be that you need symmetric encryption or a digital signature. I encourage you to ask another, separate StackOverflow question as a follow up to this one.
As a final note, I'll refer you to the Internet Security Glossary. In particular, the section named "$ asymmetric cryptography" has a precise and brief description about how "Asymmetric cryptography can be used to create algorithms for encryption, digital signature, and key agreement."
From your other (unfortunately on hold) question https://stackoverflow.com/questions/49610839/protecting-jwt-signing-and-encryption-c-sharp-solution, it sounds like you require the following:
Send a payload from the server to the client.
Only the client can read the payload, because it is encrypted.
The client can verify who sent the payload, because it is signed.
The recommended approach is to sign-and-then-encrypt. If you are wanting to use asymmetric encryption for both:
use a private to key to sign the payload,
then use a public key to encrypt the signed payload.
I have a big XML that needs to be encrypted on one server (by one c# application), and needs to be decrypted on another server (by another c# application). The XML contains the critical information for which this encryption needs to be done.
My real need is that my server that does the encryption should only know the public key and the private key is known only to the server which is doing the decryption. Also, this private key should be stored in a safe area on the server such as certificates.
What should be the steps that can help me achieve so?
Can I generate my private key and store that in certificates or the certificates will generate the private key on their own?
Also, if certificates generate the public and private key, can the public key be separated from the certificate and exported to the server where the encryption has to be done?
How the key-pair and certificate are generated depends on the software used.
The private key can be obtained from a certificate.
The general method is to encrypt data with a symmetric encryption algorithm such as AES and encrypting the symmetric key with asymmetric encryption algorithm such as RSA or EC and the public key. This is done for two reasons: 1. Asymmetric encryption is very slow compared to symmetric encryption. 2. The data length for Asymmetric encryption is limited by the key size: a typical key size is 2048-bits and that limits the data length to 245-bytes.
There is in general no way to securely store a private key (or anything) on the server other than the server being secure short of the server having an HSM or access to a TPM. The main step on making the server secure is 2-factor authentication. But if it is on a shared computer beware of root escalation exploits by other users of the server.
HSM - Hardware Encryption Module
TPM - Trusted Platform Module
Asymmetric encryption is very processor intensive and, consequently very slow. For that reason, it is not normally used to encrypt large amounts of data.
What is normally done is symmetric encryption is used to encrypt the bulk of the data and asymmetric encryption (public key) is used to encrypt the keys used in the symmetric encryption.
The encrypted keys are transmitted with the encrypted data. The keys are decrypted (private key), then using the symmetric keys the bulk data is decrypted.
This is how I have achieved it.
On my server 2, I am generating a certificate(.cer) and a private key(.pvk) using the 'makecert.exe' command. Then, using the 'pvk2pfx.exe', I am generating a .pfx file. This is the file which will now house the certificate and private key.
Now I export the certificate with just the public key to the server 1, where I encrypt the data, and on Server 2 using the certificate's private key I decrypt the data.
For learning purposes, I'm creating a chat application where the connections are done via SSL/TLS, and the messages are encrypted using AES-CBC-256 and the AES keys are encrypted with RSA-2048.
The AES key is randomly generated (AesProvider.GenerateKey()) per user per session (which means one key for every person an user is chatting with) and the IV is randomly generated (AesProvider.GenerateIV()) by passing in the key generated, each time a message is created (before being sent).
On the RSA side, I'm generating a secure random session name to store the private keys generated in containers, and sending out the public key. I'm also using the same model (one key pair per user per session) as in AES.
I should also state that I'm using HMAC-SHA512 to hash the messages and sending the HMAC key encrypted using the same public key that the AES key/Iv gets encrypted with. Since I've read that it doesn't need to be regenerated often, I'm planning on regenerate the HMAC key every 5000 or 10000 calls.
Questions:
1) Should I be creating only one RSA key pair per user and use it for all sessions, or is it good how it is right now?
2) Is using the same AES key and only changing the IV like explained above considered secure?
Not much to answer because what you are doing is the best practice aready.
Some notes though;
RSA key pairs per session is not required (and generating the key is expensve).
You can have only one 2048 bit strong RSA key throughout the lifecycle of your application or for years, since this is what even the most security demanding web applications like e-commerce sites or financial applications do.
You should have a random AES key/IV pair for each session, that is fine.
It is better to have one HMAC key per session (not process wide) since you are sending the key securely (RSA encrypted) and you are also sending the HMAC value securely (AES encrypted) on the wire.
Changing only the IV is almost equal to changing the key and IV (in a sense) because the encrypted output will be different for the same content if you change the IV.
One note however. To prevent a man-in-the-middle attack mimicking your server certificate, is your client code validating the certificate through means of signature checking, or is it just the public key that you are sending without any validation on the client side?
You should have either a self-signed persistent certificate or generate the random certificate (RSA Key Pair) as is issued by the persistent certificate (eg, CN=FrozenDeathChatServer) where the clients during installation of your client software install under the trusted root certificate authorities.
If RSACryptoServiceProvider cannot Encrypt data larger than it's KeySize, how RsaProtectedConfigurationProvider is implemented in the .Net framework?
I am working on a utility that is going to be used to encrypt/decrypt some sensitive information. My two encryption provider options are DPAPI and RSA, while DPAPI not suited for web farm kind of environment, RSA is fits because of the Export/Import options with a KeyContainer. This is a stand alone application running on a workstation.
As I am aware that Asymmetric algorithms are not designed for large data, I just tried encrypting a string of length over 400K using the code below and it works well.
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
Definitely this implies that more things are happening behind the scenes apart from the export import key options in aspnet_regiis.exe.
My understanding:
we encrypt myapp.exe.config with RsaProtectedConfigurationProvider, provide a key container name myrsakeycontainer, and export the public and private keys to an xml file myrsakeyfile.xml.
If we want myapp.exe.config to be decrypted in another computer, we import they keypair from myrsakeyfile.xml with a container named myrsakeycontainer.
this works well. I can achieve the same thing in my project via RSACryptoServiceProvider. But I can't handle data that larger than the key size that
new RSACryptoServiceProvider(cspParameters)
generated for me.
I want to be able to decrypt huge data (just in case) just the way
RsaProtectedConfigurationProvider does.
Yes I could use a RijndaelManaged (my favorite) for actual
encryption and for the symmetric key transport (export/import) I
could use the RSACryptoServiceProvider. This leaves me in a
situation that If I want to export/import the symmetric key, I should
first encrypt it with the public key or RSA, import it to another
machine, decrypt with the private key of RSA. Which is export the RSA
key pair along with the encrypted symmetric key.
But, when I export RSA key pair used by
RsaProtectedConfigurationProvider via aspnet_regiis.exe, I
believe that it exports only the public/private key pair in an xml
file and no other information (like the symmetric key information).
So, with just the RSA key pair, how does
RsaProtectedConfigurationProvider manage to derypt (huge - over
400K chars in my case) information that was encrypted on another
computer? In cases it uses a symmetric algorithm (perhaps?!) to
encrypt information, how is that symmetric key exported/imported to another
computer for decryption? Is that symmetric key part of the RSA key container exported via aspnet_regiis.exe or is the symmetric key is contrived dynamic based on an algorithm?
I could get away with a Rijndael, whose key is encrypeted with an RSA
key pair and I can export/import both the RSA key pair and the
Rijndael symmetric key to another computer. (which I have done in the past)
I am interested to know what is used inside
RsaProtectedConfigurationProvider.
Any theories? concepts? links? recommendations? please..
Similar Question - What algorithms are used by RSAProtectedConfigurationProvider in web.config encyrption?
The encrypted symmetric key is stored in the XML alongside the encrypted configuration information that the symmetric key has encrypted.
If you use Reflector to look at the code, what it does is load the XML node and use the asymmetric RSA private key to decrypt a symmetric key stored within the XML node itself.
The function that actually does this magic is here:
public virtual SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri);
Declaring Type: System.Security.Cryptography.Xml.EncryptedXml
Assembly: System.Security, Version=2.0.0.0
See the code around
this.m_document.SelectNodes("//enc:EncryptedKey", nsmgr);
This blog post has a nice writeup about how you pair Asymmetric and Symmetric algorithms in real-world practice: http://pages.infinit.net/ctech/20031101-0151.html