We divide a private key into multiple parts (by splitting key string) into N parts and distribute it to different five people. At the time of decryption we collect all keys integrate it (by concatenation) and decrypt it. Is this scheme secure?
Or is it a better idea to split key in to parts using Shamir's Secret Sharing? Which has better security ?
Related
I found several solutions where I can use the RSA Provider to Encrypt a message with the public key and Decrypt it with the private one.
But what I want to have is to Encrypt with the private key and Decrypt with the public key.
I want to store the public key in my app and encrypt a license for example on my dev machine with the private key, send it to the app and let the information decrypt with a public key.
How can I achieve that?
There are two main possibilities here:
1) You actually are referring to signing (a private key operation) and verification (a public key operation).
In RSA signing, the input message is digested, and the digest is combined with a padding scheme, then the private key applied to the padded data.
In RSA verification, the candidate message is digested, the public key is used to undo the private key application, and then the digest is used to validate the padded message. (In PKCS#1 signatures that's "look and see if it's the right answer", for PSS it's more complicated).
If this is what you mean, then you want
Signing
RSA.SignData (hashes the data, then calls SignHash)
RSA.SignHash (completes the operation, is public in case you already hashed the data and want to save on redundancy)
Verification
RSA.VerifyData (hashes the data, then calls VerifyHash)
RSA.VerifyHash (same as above)
2) You want to encapsulate arbitrary data in a transformation using the private key.
The RSA PKCS#1 standards and/or RFCs have no description of what this means. "Encrypt", in RSA, means to apply a chosen padding scheme to the data (PKCS#1 or OAEP) then perform the RSA operation with the public key. "Decrypt" means to perform the RSA operation using the private key, then remove the padding.
The built-in Encrypt and Decrypt methods are performing these operations, including knowing which key to use.
Applying the keys backwards would produce sensible results mathematically, but it doesn't make sense in practice. Assuming we keep "private" meaning "the key that is only known by one party", this means that you have data that is produced by one person that can be read by anyone. If the idea is "I want the readers to know that it was produced by [the private key holder]", then signing is a better operation: It leaves the data in plain form, letting readers do a more optimal read.
RSA encryption is further only defined as a one-shot operation, which means that as a consequence it is limited to a total number of content bytes that is less than the number of bytes in the RSA modulus (11 bytes less for PKCS#1, and bigger reductions in OAEP, depending on the chosen OAEP hash algorithm). Because signing hashes first, the amount of data being processed in RSA is of fixed size. In the normal RSA encryption case the thing being encrypted is a symmetric (AES) key, or some means of building an AES key... and that's much smaller.
In the end, the conclusion of this path is "No, .NET does not allow you to do this".
If you're transporting a license, the industry-standard approach is to sign it. Remember to include a mechanism for replacing the license-issuer key over time, such as writing down the signing certificate. Or use something like PKCS#7/CMS Signed Data, as exposed in .NET by System.Security.Cryptography.Pkcs.SignedCms, since it is a predefined format for transporting the data, signature, and signing certificates -- just check that cms.SignerInfos[0].Certificate is acceptable, and then if CheckSignature(true) doesn't throw, you're good to go.
Encrypting with the private key is signing. Some providers have a verify function that gives the decrypted signature rather than just verifying it.
I have recently been learning about public/private key encryption in my computer science lessons, and how it works in terms of data encryption/decryption. We also covered how it can be used for digital signatures. However, we didn't go into too much detail on how the actual keys are generated themselves.
I know that it begins with a very large number, which is then passed through some kind of keygen algorithm which returns two distinctive keys, one of which is private and the other is public. Are these algorithms known or are they black box systems? And does one user always have the same pair of keys linked to them or do they ever change at any point?
It just seems like a very mathematical issue, as the keys are linked, yet one is not deducible from the other.
I know that it begins with a very large number, which is then passed through some kind of keygen algorithm which returns two distinctive keys, one of which is private and the other is public.
Well, that's not entirely correct. Most asymmetric algorithms are of course based on large numbers, but this is not a requirement. There are, for instance, algorithms based on hashing, and hashing is based on bits/bytes, not numbers.
But yes, for asymmetric algorithms usually contain a specific algorithm to perform the key pair generation. For instance, asymmetric encryption consists of a triple Gen, Enc and Dec where Gen represents the key pair generation. And the key pair of course consists of a public and a private part.
RSA basically starts off by generating two large random primes, it doesn't start with a single number necessarily.
Are these algorithms known or are they black box systems?
They are known, and they are fundamental to the security of the system. You cannot use just any numbers to perform, e.g., RSA. Note that for RSA there are different algorithms and configurations possible; not every system will use the same Gen.
And does one user always have the same pair of keys linked to them or do they ever change at any point?
That depends on the key management of the system. Usually there is some way of refreshing or regenerating keys. For instance X.509 certificates tend to have a end date (the date of expiry or expiration date), so you cannot even keep using the corresponding private key forever; you have to refresh the certificates and keys now and then.
It just seems like a very mathematical issue, as the keys are linked, yet one is not deducible from the other.
That's generally not correct. The public key is usually easy to derive from the private key. For RSA the public exponent may not be known, but it is usually set to a fixed number (65537). This together with the modulus - also part of the private key - makes the public key. For Elliptic Curve keys a private random value is first produced and the public key is directly derived from it.
You can of course never derive the private key from the public key; that would make no sense - it would not be very private if you could.
In RSA the generated two numbers p and q are very large prime numbers more or less the same size, which are used to calculate N which derives the public/private keys using modulo arithmetic.
The following answer in crypto.stackexchange.com describes in more details how we can start from a random (large) number and use Fermat test and Miller-Rabin tests to reach a number that is very probable to be prime.
I need to use RSA encryption in a environment where byte size of the keys are important.
I don't want to risk security breaking, so I wondered if you could have one person transmit his key first using (2048 bit) and then have the other transmit his key of size (256bit) encrypted with the other guy's key. And if this would still provide a secure scheme?
PS: I realize 256 bit would increase from the encryption and you can ignore the man-in-middle problem.
TL;DR: Does keeping public key secret allow for a smaller key size?
Typically one would use RSA and other asymmetric algorithms specifically for the purpose of exchanging keys. The security of RSA has to do with factoring large primes, which is why their key sizes are typically so much longer than symmetric keys for algorithms such as AES. What you don't want to do is reduce the RSA key size in your scheme. So if what you're doing is creating a 256 bit AES key and then using AES thereafter for encryption I think the security scheme will work. Public key cryptography is much slower than symmetric encryption therefore for performance and other reasons you don't want to use RSA.
As to your question regarding keeping the public key secret, I think that goes against what RSA is meant for. A public key is meant to be public.
The implementation can have failings as well, for example SSL 3 was found to have a padding oracle vulnerability in 2014. I would suggest you use a standard implementation like TLS rather than trying to make your own protocol. Secure protocols are typically the most difficult problems in cryptography.
A question for cryptography experts. Imagine we have a conceptual Notes.app:
There are notes (title|content) stored as AES-256 encrypted strings
Application has to present a list of all notes (titles) in a list on its main window
Every title|content is encrypted with a key, generated from a password and a salt
Let's imagine the key generation algorithm takes ~80ms on a mobile device to generate a key
With the following conditions, it would take almost 1 second to decrypt 10 note titles. But what if there are lots of notes?
My 2 pennies on the problem: Encrypt all notes with different initialization vectors, but also with identical salt. That would allow me to generate a decryption key only once and decrypt lots of notes fast.
The question: doing so we would end up with lots of different notes, encrypted with an identical key. Does that somehow compromise the security of AES encryption? Is it possible that knowing there's a bunch of files with not just identical password, but also identical salt somehow makes it possible to crack the encryption?
Thanks for your thoughts
AES-256 do not use a salt. But I guess you use the salt together with the password in a PBE algorithm to generate the key. Usually this kind of PBE algorithms are constructed to be computational expensive - thus the 80 ms you see on your mobile.
When encrypting different messages, you could instead of using different salts to create different keys, just use different initialization vectors (IV) but the same key. The different IV ensures that messages that starts with the same block encrypts to different messages.
Assuming a keystore is secure and one needs to service around a million keys, is it better to generate asymmetric keys in real-time or is it better to generate a bunch of keys and store them to be used as and when required?
Edit 1: By real time I mean generate a key pair when a user registers for the first time, from then on that key pair is used for all communication with the user.
Asymmetric keys have a public part and a private part; the public part is used to perform the operation which complements that which is done with the private part (e.g. you sign with the private key, and you verify the signature with the public key; or you encrypt data with the public key, and decrypt it with the private key). The point of asymmetric keys is that the private and public parts can be known by distinct entities; namely, that the public part is, well, public (everybody knows it) while the private part remains private.
Consequently, generating an asymmetric key "in real-time" makes little sense in most situations: what gives some value to a private key is that the public key is already known to some other party.
One can still imagine some situations in which "real-time" generation of asymmetric keys can be of use. For instance, SSL connections using one of the "ephemeral Diffie-Hellman" cipher suites: the DH keys, which can be called "asymmetric", are generated for each connection, the public part being then signed by the server (with another asymmetric key, which is not generated on-the-fly: the public key is the one in the server certificate) and then sent to the connecting client. In such a situation, pre-generating DH key pairs and storing them could be viewed as a kind of optimization, but a bad one since DH key pair generation is very fast, and private key storage is a complex and delicate issue.
Edit: if your problem is about key generation upon user registration vs key generation and storage in advance: assuming that server-side key generation is indeed what you want, key generation and storage in advance is worthwhile only as an optimization, if on-the-fly generation proves to be too expensive to handle peaks (occasionally, many users trying to register at the same time). I suggest that you try and bench and make sure that the problem really exists, before implementing a "solution", because private key secure storage is somewhat tricky. RSA key generation is quite fast (on a basic PC, you can easily generate a dozen RSA keys per second), and with discrete-log (DSA, Diffie-Hellman, El-Gamal) or elliptic-curve based cryptosystems, it is even considerably faster (e.g. ten thousands new EC key pairs per second, with a PC).