How to Generate Unique Public and Private Key via Rsa

How to Generate Unique Public and Private Key via RSA

What I ended up doing is create a new KeyContainer name based off of the current DateTime (DateTime.Now.Ticks.ToString()) whenever I need to create a new key and save the container name and public key to the database. Also, whenever I create a new key I would do the following:

public static string ConvertToNewKey(string oldPrivateKey)
{

// get the current container name from the database...

rsa.PersistKeyInCsp = false;
rsa.Clear();
rsa = null;

string privateKey = AssignNewKey(true); // create the new public key and container name and write them to the database...

// re-encrypt existing data to use the new keys and write to database...

return privateKey;
}
public static string AssignNewKey(bool ReturnPrivateKey){
string containerName = DateTime.Now.Ticks.ToString();
// create the new key...
// saves container name and public key to database...
// and returns Private Key XML.
}

before creating the new key.

RSA- Is it possible to generate a private key from a given public key?

No, that's not possible. The modulus is shared between the private and public key and is unique for the key pair. You need to factor the modulus into the separate primes to generate a valid private key from it. This is called the RSA problem and it is what makes RSA suitable for asymmetric cryptography.

The only times when a modulus can be factored is if the RSA key pair generation is broken, or when the underlying random number generator repeats over multiple instances, and the attacker learns the key pair through that. Then there are side channels, bad key management...

Use RSA private key to generate public key?

openssl genrsa -out mykey.pem 1024

will actually produce a public - private key pair. The pair is stored in the generated mykey.pem file.

openssl rsa -in mykey.pem -pubout > mykey.pub

will extract the public key and print that out. Here is a link to a page that describes this better.

EDIT: Check the examples section here. To just output the public part of a private key:

openssl rsa -in key.pem -pubout -out pubkey.pem

To get a usable public key for SSH purposes, use ssh-keygen:

ssh-keygen -y -f key.pem > key.pub

How to generate RSA public key from private key?

If the private key is stored in CRT format (Chinese Remainder Theorem), there is no math involved; the format includes the public exponent. This is how OpenSSL tools "create" a public key from a private key.

If the private is not stored in CRT format, it's generally not feasible to compute the public exponent given the private exponent. You can, however, guess common public exponents and easily verify your guess.

Mathematically, in order to quickly compute one exponent using the other, you need to know the totient, a number computed from the factors of the modulus. And of course the security of RSA is predicated on the infeasibility of factoring the modulus. This relationship is symmetrical; it doesn't matter whether you know the public exponent and try to compute the private exponent, or vice-versa.

How to generate private public key in JAVA using no external libraries

I use JShell to demonstrate the basic public-private key generation just using Java's BigInteger:

jshell> import java.math.BigInteger;
jshell> var rnd = new java.security.SecureRandom();
rnd ==> Hash_DRBG,SHA-256,128,reseed_only

First we need 2 primes

jshell> var p1 = BigInteger.probablePrime(512, rnd);
p1 ==> 1176110601168217581401499298469596353224364190716 ... 72507270343325790065694831

jshell> var p2 = BigInteger.probablePrime(512, rnd);
p2 ==> 1001341560055006431459083188828513502474297271020 ... 34378293673605844490263567

Next we calculate the public key. 0x10001 is a common exponent for the public key.

jshell> var n = p1.multiply(p2);
n ==> 1177688424171014462551464978852125044384293220079 ... 24824881562893076179522177

jshell> var e = BigInteger.valueOf(0x10001);
e ==> 65537

The public key is e and n.
Now the private part.

jshell> var phi = p1.subtract(BigInteger.ONE).multiply(p2.subtract(BigInteger.ONE));
phi ==> 1177688424171014462551464978852125044384293220079 ... 17939317545961441623563780

jshell> var d = e.modInverse(phi);
d ==> 7023685818262702180949167670691999860354377649273 ... 38390163809778429090416313

The private key is now d and n.

Let's test it:

jshell> var secret = BigInteger.valueOf(1337);
secret ==> 1337

jshell> var enc = secret.modPow(e, n);
enc ==> 1059982071031392497566614763259148320406936402012 ... 39171914529632475117049800

jshell> enc.modPow(d, n);
$11 ==> 1337

We could send enc over the wire, and nobody could decrypt it without the knowledge of the private key. Well, at least in theory. In practice, you should pad your messages.

RSA - Can you create a public key from a private key?

Private and public key are created together. Also, the standard storage format for a RSA private key includes all the public key fields, because it is useful for optimized implementations and masking (protection against some side-channel attacks). See the RSA standard itself: PKCS#1.

Edit: question has been edited, it was originally RSA-only. For other asymmetric algorithm, there is no requirement that the public key may be derived from the private key, nor is there any requirement of the contrary. For discrete logarithm-based algorithms (Diffie-Hellman, El-Gamal, DSA, and the elliptic curve variants of all of these), the public key is easily computed from the private key. It is possible to conceive a degenerate RSA in which knowledge of the private key does not allow reconstruction of the public key, but this requires not storing a few key elements which are needed for good performance (in full details, storing the RSA modulus factors allows for a 4x speed enhancement through the Chinese Remainder Theorem, so everybody stores the factors). On a more conceptual basis, the public key is, well, public, so it is assumed that "everybody" knows it; in practical terms, private key storage format almost always include provisions for storing the public key as well, or at least sufficient data to rebuild the public key.

RSA Cipher, how to secure save public and private keys?

Every strategy you'll consider will still have the problem where if you yourself have access to that secret, anyone with the same level of access will have it as well. You can never fully secure a system, you can just make it harder for someone to break in. If you make it harder to break in than the profit of breaking in, people won't want to go through the trouble, and you can probably keep things safe.

To solve this kind of a problem, you have to frame it based on from whom you are trying to protect a secret. You are correct that leaving the secret (the private half of your keys) in your code means that anyone who can see your code can see the encryption key. However, is this reasonable for your threat model? Is it easy for someone else to gain access to your file system? Or would it be easier for someone to get access to your database backups instead?

If they have access to your filesystem, does that mean they also have root on the machine? Your options for protecting against someone who has full access and control of the machine hosting your application are pretty limited! If they can attach debugging tools to the process they may even be able to read your secret from memory anyway.

Here's a series of escalating levels of protection:

  1. (not at all secure) Keep your secret in code. As long as nobody can see your code (such as in a public Github repo), then they can't see your secret.
  2. (little better) Keep your secret in a file that only lives in production. Now if the attacker has access to an offline backup of your data, they cannot read the contents without that additional file.
  3. (pretty good) Type your secret in on deploy. This now protects against if the attacker is able to download the contents of your production filesystem. You can either type in the literal secret, or keep a file containing your key encrypted with an easier-to-remember encryption secret that you type in on deploy.
  4. (extra paranoid) Use a service that generates the encryption keys for you, and use a deployment platform that integrates with it. This is a pretty extensive industry with many competing products, and I do not want to endorse any particular one. You have your vendor generate the encryption keys for you, and your deployment vendor coordinate with it to inject those secrets on deploy. This protects against if an attacker has installed a keylogger on your laptop, where typing in the secret on deploy would leak the secret.


Related Topics



Leave a reply



Submit