user2864778
user2864778

Reputation: 333

Extract RSA private key from Cryptico.js

I believe this is a pretty basic question, but I'm starting the studies in JavaScript and in RSA, so I'm a little bit lost. I just downloaded the library Cryptico, which gives me an easy to use RSA key gen/encryption/decryption. The public part of the generated RSA Key, can be extracted easily just using the command:

publicKeyString(RsaKey)

Which is:

my.publicKeyString = function(rsakey) 
{
    pubkey = my.b16to64(rsakey.n.toString(16));
    return pubkey; 
}

The rsakey.n is defined while generating the key in the function:

function RSAGenerate(B, E)
{
    var rng = new SeededRandom();
    var qs = B >> 1;
    this.e = parseInt(E, 16);
    var ee = new BigInteger(E, 16);
    for (;;)
    {
        for (;;)
        {
            this.p = new BigInteger(B - qs, 1, rng);
            if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
        }
        for (;;)
        {
            this.q = new BigInteger(qs, 1, rng);
            if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
        }
        if (this.p.compareTo(this.q) <= 0)
        {
            var t = this.p;
            this.p = this.q;
            this.q = t;
        }
        var p1 = this.p.subtract(BigInteger.ONE);
        var q1 = this.q.subtract(BigInteger.ONE);
        var phi = p1.multiply(q1);
        if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0)
        {
            this.n = this.p.multiply(this.q);
            this.d = ee.modInverse(phi);
            this.dmp1 = this.d.mod(p1);
            this.dmq1 = this.d.mod(q1);
            this.coeff = this.q.modInverse(this.p);
            break;
        }
    }
}

But the private part of the key, I just can't understand how to extract, so I'll be able to save public/private key parts and available for later using.

Library Documentation: https://github.com/wwwtyro/cryptico

Upvotes: 1

Views: 2616

Answers (1)

Artjom B.
Artjom B.

Reputation: 61952

RSA is defined in such a way that the values contained in a public key make up a subset of the values contained in the private key. So your private key is already rsakey. Other public key schemes work differently where public and private key values are completely distinct.

Furthermore rsakey.n doesn't fully define the public key. You need at least the public exponent e. It is often simply set to 65537, so this might be hardcoded if you never need to change the key or upgrade the scheme. It's the E in RSAGenerate. It is ignored in this case, because

A (seeded) random RSA key is generated with Tom Wu's RSA key generator with 3 as a hard-coded public exponent.

You can choose a similar encoding of the private key as the public key, but since it has to hold multiple values, I opted for JSON serialization:

(function(c){
    var parametersBigint = ["n", "d", "p", "q", "dmp1", "dmq1", "coeff"];

    c.privateKeyString = function(rsakey) {
        var keyObj = {};
        parametersBigint.forEach(function(parameter){
            keyObj[parameter] = c.b16to64(rsakey[parameter].toString(16));
        });
        // e is 3 implicitly
        return JSON.stringify(keyObj);
    }
    c.privateKeyFromString = function(string) {
        var keyObj = JSON.parse(string);
        var rsa = new RSAKey();
        parametersBigint.forEach(function(parameter){
            rsa[parameter] = parseBigInt(c.b64to16(keyObj[parameter].split("|")[0]), 16);
        });
        rsa.e = parseInt("03", 16);
        return rsa
    }
})(cryptico)

Upvotes: 6

Related Questions