How to safely store secret key? [closed] - encryption

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
As I have developed my app using openFL which uses haxe, and I am about to start the activation part of my software, I wonder how would I safely store my encryption secret key? would I just hard code it into my app??!
I will be using this key to encrypt data before sending to server, and I will be using it to de-encrypt data received from server too.
Any one can recommend best practices followed in such case?

This sounds like a job for asymmetric encryption.
Create a key pair at your server, store public and private keys. The private key should be kept safe, the key size should be 2048 bits or more;
Include the public key in your application;
The application uses a secure random generator to create an AES key;
The data is encrypted using CBC and PKCS#7 padding, also include a HMAC (possibly with yet another random AES key);
Encrypt the key(s) with the RSA algorithm and the public key;
The server can now decrypt the AES keys using the private key and decrypt the data with the retrieved keys. Then verify the MAC, if you included it in your protocol. Finally decrypt the ciphertext to retrieve the plaintext.
This scheme is called hybrid encryption because it uses both symmetric and asymmetric encryption. Beware of padding oracle attacks (which leak all the plain text to an attacker) if you don't use a MAC. Always verify the MAC before decrypting.
You can store an RSA public key within your application. With this public key you can encrypt an AES key (using PKCS#1 OAEP or v1.5 padding).

Related

Proper asymmetric file encryption in Go

I need a way to allow multiple people encrypting various files but only one party been able to read them all. I wrote a program in Go by following various online examples but at some point I got the following error:
Error from encryption: crypto/rsa: message too long for RSA public key size
Is RSA the wrong way to go? Is it ok if I break the file into multiple chunks and encrypt them? Is there an asymmetric block cipher that I can easily use?
I read the discussion here and it is said that RSA is not the proper way to go.
Can you also provide with an example?
If you need public key asymmetric encryption for data larger than the key size you need to use hybrid encryption. Essentially this is how HTTPS works.
Hybrid encryption is where the data is encrypted with symmetric key encryption such as AES and that key is encrypted with asymmetric key encryption such as RSA or EC (Elliptic Curve) Cryptography.
Do not break the file into multiple chunks and encrypt them.
So I ended up using GPG and my service has one unique private key and I share the public one with my users.

RSACryptoServiceProvider and Web.config encryption

I am new to cryptography. I want to encrypt the connection string section and some other section in the web.config. I know this can be accomplished using RSACryptoServiceProvider.
But I am not sure about the Key which is being used by the default RSACryptoServiceProvider and the key size.
As per our organization security policy the key size should be 196 bit and we have to share the Key with security team which is used for encryption.
When we use the default encryption what will be key used internally by asp.net for encryption/decryption and the key size?
In-order to use a custom key which can be shared with security team do we need to create a custom class by inhering RSACryptoServiceProvider?
Also RSA Key Container is bit confusing. Is it a container for the Key or the Key itself
Please advice.
RSA key container files which are exported from aspnet_regiis.exe are indeed containers for the key. They are XML files. Actually, as RSA is public key crypto, the key container holds both the public key and private key (if you export both).
When you perform web.config or app.config encryption via aspnet_regiis.exe, and you do not specify a provider, it will use the value of "defaultProvider". See http://msdn.microsoft.com/en-us/library/zhhddkxy(v=vs.100).aspx. The encrypted output will list the provider name (so that you know how to decrypt it). It appears the default name of the default provider is "RsaProtectedConfigurationProvider". That crypto provider uses a key. The default key has a default name of "NetFrameworkConfigurationKey" (see http://blogs.msdn.com/b/mosharaf/archive/2005/11/17/protectedconfiguration.aspx). The key with that name will have a different value on every machine and is generated when .NET is installed.
A key length of 196 bits sounds like your security team expects you to be performing symmetric key encryption (not asymmetric PKC) of some sort. For example, people brag about their AES key lengths being 256 bits. The .NET 4.0 aspnet_regiis.exe command for creating a custom RSA crypto provider and key use a key size of 2048 bits (although 1024 is not uncommon from days of yore). I imagine the default RSA provider and default key use default values for key lengths. But to be sure, you might want to export the default key, and inspect it yourself. The -pc and -px switches and their associated options (like -size) are documented at http://msdn.microsoft.com/en-us/library/vstudio/k6h9cz8h(v=vs.100).aspx.
If you need to be very specific about a private key, which would be durable beyond a machine reimaging, and would be used by many nodes in a server farm, and which needs to be held in escrow by the security team, you probably want to invest the time in creating a non-default crypto provider of the RsaProtectedConfigurationProvider type (not inventing your own CSP class as an alternative to RsaProtectedConfigurationProvider).
One last thing to note, web.config XML encryption is performed in a multi step process. First, the encryption process generates a random symmetric key (which is short in comparison to an RSA key) which will be used to encrypt a plaintext corpus. The plaintext is encrypted with the symmetric key (after the corpus is normalized for whitespace, etc). Then, the symmetric key (which is short compared to the corpus) is encrypted using an RSA public key. If the whole plaintext corpus was encrypted with an RSA public key, it would take a long time to decrypt. So when you look at a block of encrypted XML in a web.config encrypted you will really see two things: an encrypted key section, and an encrypted data section. To decrypt the ciphertext, ASP.NET needs to first decrypt the encrypted symmetric key, and then use the decrypted key to decrypt the stuff you actually want as plaintext.
There is an example of the two-levels of encryption at "Problem with decrypting xml document". What is apparent (and perhaps troubling), is that the RSA crypto provider uses Triple DES in CBC mode for the symmetric crypto algorithm underlying the RSA PKC which you think is really providing the encryption. See this person's frustration around trying to change the symmetric algorithm to AES, for example, Change Microsoft Config File Encryption Method From TripleDES. Triple DES is only recommended for use until 2030 in very ideal scenarios (see http://en.wikipedia.org/wiki/Triple_DES#Security) by the algorithm's endorsers (NIST). NIST had a bake-off years ago for a replacement symmetric algorithm suite, which they have chosen and endorsed as AES (http://en.wikipedia.org/wiki/Advanced_Encryption_Standard). So to use AES-192 or AES-256, you would need to invent your own CSP class as an alternative to RsaProtectedConfigurationProvider, then make it available for creating providers and performing encrypt/decrypt operations from ASP.NET.
Here is another stack-overflow article which is relevant: ASP.NET Encryption - aspnet_regiis - Farm.
Here is a guide to creating/exporting RSA crypto providers and keys for spreading around in a farm, for example: http://msdn.microsoft.com/en-us/library/2w117ede(v=vs.100).aspx

confusion in public and private key [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
in Encryption and decryption same key is use to to convert plan text to cipher and cipher to plan text. so why in public key cryptograpy method sender Encrypt using receiver public key and receiver decrypt using his own private key ?
What you initially refer to is symmetric encryption (shared key), which allows 2 entities to communicate securely based on a single shared key that is only known to the two entities. This key can be exchanged several ways, but can't be publicized for obvious reasons.
Asymmetric encryption (public/private key) allows 2 entities to communicate securely as follows:
If one party wants to accept secure (encrypted) information, they need a key that isn't visible to the world (private), but they also have to be able to provide a key to anyone who wants to send encrypted information (public).
So I can give my public key out to the whole world and know the data is secure since only I have the private key, therefore I'm the only one who can decrypt it.
See Asymmetric Encryption in this Microsoft article: http://support.microsoft.com/kb/246071
Because it wouldn't be secure the other way around, or feasible either. Only the recipient has his private key, so nobody else can use it.

Can AES Encryption and RSA Digital Signature Scheme work together for file encryption?

I am planning on file encryption during file transfer from physical storage to physical storage as my final year project at my high school.
My question is, can AES Encryption and RSA Digital Signature Scheme be used as file encryption? Currently I am focusing on text files (.doc, .txt).
I've got the following protocol in mind:
the file will be encrypted using AES Encryption
the private key from RSA Encryption will be the signature for the file
the public key will verifies the signature during decryption
I am not sure about the bit sizes of the keys to use, either 256 bit AES and 1024 bit RSA.
Most of the time AES and RSA are used together in the following way:
create an asymmetric key pair and keep the private key confidential and the public key in a trusted keystore
create a symmetric data encryption key and encrypt the data with it (e.g. using AES-CBC and a random IV)
encrypt the symmetric data encryption key using the public key of the key pair
create a signature with a private key (if possible, using a separate key pair), using e.g. PKCS#1 using the SHA-256 hash algorithm
store the encrypted data (+IV), the encrypted key and the signature
To verify
retrieve the data etc.
verify the signature using the public key from the trust store
decrypt the symmetric key using the private key (protected by a password, stored on an USB stick or smart card etc)
decrypt the data
You will need some way to store the data. It's best to use a common format for this such as Cryptographic Message Syntax. For key sizes see http://www.keylength.com/ e.g. using the NIST or ECRYPT II recommendations. I would suggest matching sizes, e.g. AES-128 bits, RSA 3072 bits and SHA-256 for the signature.

What is the difference between encrypting and signing in asymmetric encryption? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
What is the difference between encrypting some data vs signing some data (using RSA)?
Does it simply reverse the role of the public-private keys?
For example, I want to use my private key to generate messages so only I can possibly be the sender. I want my public key to be used to read the messages and I do not care who reads them. I want to be able to encrypt certain information and use it as a product-key for my software. I only care that I am the only one who can generate these. I would like to include my public key in my software to decrypt/read the signature of the key. I do not care who can read the data in the key, I only care that I am the only verifiable one who can generate them.
Is signing useful in this scenario?
When encrypting, you use their public key to write a message and they use their private key to read it.
When signing, you use your private key to write message's signature, and they use your public key to check if it's really yours.
I want to use my private key to generate messages so only I can possibly be the sender.
I want my public key to be used to read the messages and I do not care who reads them
This is signing, it is done with your private key.
I want to be able to encrypt certain information and use it as a product key for my software.
I only care that I am the only one who can generate these.
If you only need to know it to yourself, you don't need to mess with keys to do this. You may just generate random data and keep it in a database.
But if you want people to know that the keys are really yours, you need to generate random data, keep in it a database AND sign it with your key.
I would like to include my public key in my software to decrypt/read the signature of the key.
You'll probably need to purchase a certificate for your public key from a commercial provider like Verisign or Thawte, so that people may check that no one had forged your software and replaced your public key with theirs.
In RSA crypto, when you generate a key pair, it's completely arbitrary which one you choose to be the public key, and which is the private key. If you encrypt with one, you can decrypt with the other - it works in both directions.
So, it's fairly simple to see how you can encrypt a message with the receiver's public key, so that the receiver can decrypt it with their private key.
A signature is proof that the signer has the private key that matches some public key. To do this, it would be enough to encrypt the message with that sender's private key, and include the encrypted version alongside the plaintext version. To verify the sender, decrypt the encrypted version, and check that it is the same as the plaintext.
Of course, this means that your message is not secret. Anyone can decrypt it, because the public key is well known. But when they do so, they have proved that the creator of the ciphertext has the corresponding private key.
However, this means doubling the size of your transmission - plaintext and ciphertext together (assuming you want people who aren't interested in verifying the signature, to read the message). So instead, typically a signature is created by creating a hash of the plaintext. It's important that fake hashes can't be created, so cryptographic hash algorithms such as SHA-2 are used.
So:
To generate a signature, make a hash from the plaintext, encrypt it with your private key, include it alongside the plaintext.
To verify a signature, make a hash from the plaintext, decrypt the signature with the sender's public key, check that both hashes are the same.
There are two distinct but closely related problems in establishing a secure communication
Encrypt data so that only authorized persons can decrypt and read it.
Verify the identity/authentication of sender.
Both of these problems can be elegantly solved using public key cryptography.
I. Encryption and decryption of data
Alice wants to send a message to Bob which no one should be able to read.
Alice encrypts the message with Bob's public key and sends it over.
Bob receives the message and decrypts it using his private Key.
Note that if A wants to send a message to B, A needs to use the Public
key of B (which is publicly available to anyone) and neither public
nor private key of A comes into picture here.
So if you want to send a message to me you should know and use my public key which I provide to you and only I will be able to decrypt the message since I am the only one who has access to the corresponding private key.
II. Verify the identity of sender (Authentication)
Alice wants to send a message to Bob again. The problem of encrypting the data is solved using the above method.
But what if I am sitting between Alice and Bob, introducing myself as 'Alice' to Bob and sending my own message to Bob instead of forwarding the one sent by Alice. Even though I can not decrypt and read the original message sent by Alice(that requires access to Bob's private key) I am hijacking the entire conversation between them.
Is there a way Bob can confirm that the messages he is receiving are actually sent by Alice?
Alice signs the message with her private key and sends it over. (In practice, what is signed is a hash of the message, e.g. SHA-256 or SHA-512.)
Bob receives it and verifies it using Alice's public key. Since Alice's public key successfully verified the message, Bob can conclude that the message has been signed by Alice.
Yeah think of signing data as giving it your own wax stamp that nobody else has. It is done to achieve integrity and non-repudiation. Encryption is so no-one else can see the data. This is done to achieve confidentiality. See wikipedia http://en.wikipedia.org/wiki/Information_security#Key_concepts
A signature is a hash of your message signed using your private key.
Signing is producing a "hash" with your private key that can be verified with your public key. The text is sent in the clear.
Encrypting uses the receiver's public key to encrypt the data; decoding is done with their private key.
So, the use of keys is not reversed (otherwise your private key wouldn't be private anymore!).
You are describing exactly how and why signing is used in public key cryptography. Note that it's very dangerous to sign (or encrypt) aritrary messages supplied by others - this allows attacks on the algorithms that could compromise your keys.
Signing indicates you really are the source or vouch for of the object signed. Everyone can read the object, though.
Encrypting means only those with the corresponding private key can read it, but without signing there is no guarantee you are behind the encrypted object.
Functionally, you use public/private key encryption to make certain only the receiver can read your message. The message is encrypted using the public key of the receiver and decrypted using the private key of the receiver.
Signing you can use to let the receiver know you created the message and it has not changed during transfer. Message signing is done using your own private key. The receiver can use your public key to check the message has not been tampered.
As for the algorithm used: that involves a one-way function see for example wikipedia. One of the first of such algorithms use large prime-numbers but more one-way functions have been invented since.
Search for 'Bob', 'Alice' and 'Mallory' to find introduction articles on the internet.
What is the difference between encrypting some data vs signing some data (using RSA)?
Encryption preserves confidentiality of the message ("some data"), while signing provides non-repudiation: i.e. only the entity that signed it could have signed it. There are functional differences as well; read on.
Does it simply reverse the role of the public-private keys?
Absolutely not. The use of the same private keys for signing and decryption (or, likewise, the same public keys for verification and encryption) is frowned upon, as you should not mix purposes. This is not so much a mathematical issue (RSA should still be secure), but a problem with key management, where e.g. the signing key should have a shorter live and contain more protection before it is used.
For the same message, you should use the senders private key for signing and the receivers trusted public key for encryption. Commonly sign-then-encrypt is used otherwise an adversary could replace the signature with his own. Likewise you should use the private key of the receiver for decryption and the trusted public key of the sender for verification.
Furthermore, you should understand that signature generation doesn't use "encryption with the private key". Although all RSA operations are based upon modular exponentiation, the padding scheme is entirely different for signature generation. Furthermore, the public key has entirely different properties than the RSA private key in all practical uses of RSA.
For example, I want to use my private key to generate messages so only I can possibly be the sender.
That's non-repudiation property, which can be achieved by signing.
I want my public key to be used to read the messages and I do not care who reads them.
The public key should be considered known by all. If you want everybody to read the messages, then you simply do not encrypt them.
Signing will generally not influence the content of the message. The message is is considered separate from signatures. Officially such signatures are known as "signatures with appendix" where the appendix is the message. It's a bit weird name as the message is considered more important than the signature over it, but yeah. Only few signatures offer (partial) message recovery; they are not used much anymore and are generally considered deprecated.
Note that signature protocols such as CMS may deploy a container format that includes both the message and the signature. In that case you'd need first get the - still unencrypted - message out of the container, much like unzipping a file from a plain .zip archive. So the message may be hidden from view and cannot be directly used in that case.
I want to be able to encrypt certain information and use it as a product-key for my software. I only care that I am the only one who can generate these.
Encryption is used to achieve confidentiality. In the past RSA signature generation was often thought of as "encryption with the private key". However, the operations are quite different as explained above, and the later standards desperately try and separate encryption and signature generation.
I would like to include my public key in my software to decrypt/read the signature of the key. I do not care who can read the data in the key, I only care that I am the only verifiable one who can generate them.
Yes, this is called establishing trust in the public key. However, protecting your program code is very different from protecting messages. You can perform code signing but then you'd need something to check the signature outside of your code. There are operating systems that offer this.
There is Microsoft Authenticode for instance. Application stores like the iStore and Android app store may or may not use code signing, but they offer some reassurance that your application isn't cloned or at least not cloned within the store. Cryptography is not always the solution after all.
Keeping your code from being cloned / altered at all is much harder, and you'd be solidly in DRM territory if you go that way.
Is signing useful in this scenario?
Yes, absolutely. It can certainly help making sure that the messages were only signed by you, if there is trust in the public key. If it can be helpful for authenticating your application code / integrated public key depends entirely on the environment that you expect to run the code in.
In your scenario, you do not encrypt in the meaning of asymmetric encryption; I'd rather call it "encode".
So you encode your data into some binary representation, then you sign with your private key. If you cannot verify the signature via your public key, you know that the signed data is not generated with your private key. ("verification" meaning that the unsigned data is not meaningful)
Answering this question in the content that the questioners intent was to use the solution for software licensing, the requirements are:
No 3rd party can produce a license key from decompiling the app
The content of the software key does not need to be secure
Software key is not human readable
A Digital Signature will solve this issue as the raw data that makes the key can be signed with a private key which makes it not human readable but could be decoded if reverse engineered. But the private key is safe which means no one will be able to make licenses for your software (which is the point).
Remember you can not prevent a skilled person from removing the software locks on your product. So if they have to hack each version that is released. But you really don't want them to be able to generate new keys for your product that can be shared for all versions.
Python
The PyNaCl documentation has an example of 'Digital Signature' which will suite the purpose. http://pynacl.readthedocs.org/en/latest/signing/
and of cause NaCl project to C examples
What is the difference between encrypting some data vs signing some data (using RSA)?
RSA merely the only public-key cryptosystem that naively supports both public-key encryption and digital signatures.
This usually confuses beginners since various sources/lecturers that say
RSA decryption is the RSA signature.
No, it is not!
The confusing comes from the textbook RSA
the textbook RSA encryption;
message m and calculates c = m^e mod n for encryption and m = c^d mod n for the decryption.
the textbook RSA signatures;
message m and calculates sg = m^d mod n for verification and m == sg^e mod n for the signature verification.
Both are not secure and they are not used in the real-life!
Does it simply reverse the role of the public-private keys?
No, it is not!
Encryption
For RSA encryption one must be using either RSASSA-PKCS1-v1_5 padding or Optimal Asymmetric Encryption Padding (OAEP). These paddings have overhead to the message. For example, PKCS1-v1_5 defined as
It has an EM structure as this
EM = 0x00 || 0x02 || PS || 0x00 || M.
so what are they;
PS is at least eight FFs block
M is the message
the first 0x00 guarantees that EM is less than the modulus.
The rest details like the size of FF block etc. can be found in rfc 8017 section 7.2.1
So it has a special message structure to be secure which is proven to be secure very lately (2018). The padding has at least 11-byte overhead.
Signature
The correct term for signature is signing and verification. For secure signing, RSA needs RSA-PSS (Probabilistic signature scheme). The structure is a bit complex, a picture will tell most of it
Once you hash the message and properly padded, then you can use your private key to sign your padded message!
For the verification, use the public key on the signed message and verify using the padding rules.
Prefer OAEP since RSASSA-PKCS1-v1_5 hard to implement correctly and those incorrect implementations caused many attacks over the year despite that is is proven to be secure.
Let finish all with the Cornell University page;
RSA Signing is Not RSA Decryption

Resources