Pergunta

I can successfully generate a public/private keypair using jsbn on the client side. Encrypting and decrypting client side with these keys is fine. I can also transmit that public key to the server and store it in MySQL via PHP.

I cannot encrypt something in PHP using the jsbn public key, and then decrypt it client side using the jsbn private key.

// attempting to encrypt in PHP using the jsbn public key.
// (this public key came from jsbn client side)
$jsbn_public_key = '763989d1f75a779dae752ac236b011e85f9496bb414d72f5e89bf44274a942277fab2d4f5c58a57634d4000eecc8009d2efaeff17aa4a0efae2c4d41f3423be88be043628c6bac86f97deaadf23231793e6fa02550fb2ca65b2600e074205d23338e28ab3c5e92265e6bd7995c173085e3dc042e59ef464c5ed058c3ad863911';
$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1); // tried various options here.
$public_key = array(
    'n' => new Math_BigInteger($jsbn_public_key, 16),
    'e' => new Math_BigInteger('65537', 10), // same value as jsbn
);
$rsa->loadKey($public_key,CRYPT_RSA_PUBLIC_FORMAT_RAW);  // tried various options here.
$ciphertext = $rsa->encrypt($value);
$ciphertext_web_safe = bin2hex($ciphertext); // I think this is where the problem is!
// $ciphertext_web_safe looks something like this:
// 1b02bee0422028accba74f37e6e6974125fd16bdf83a72b8d6462e140ee6e85adae869fddc5e83635aaf90bc6074a3128890eeadf9537c33ebdfd665e16a3f1b617fa2fa5454f469e84f86d77ffcbc234dfc8a32291fbc84df61a0098c97fd90bb10204f68e783d9996678cd7853f3cbd932a4a067cb7f4f9eb62ca0542964f6
// which is exactly the same length as an encrypted string generated by jsbn

And here's the client side encryption:

var my_rsa = {
    ....
    e: "65537",
    public_key: '763989d1f75a779dae752ac236b011e85f9496bb414d72f5e89bf44274a942277fab2d4f5c58a57634d4000eecc8009d2efaeff17aa4a0efae2c4d41f3423be88be043628c6bac86f97deaadf23231793e6fa02550fb2ca65b2600e074205d23338e28ab3c5e92265e6bd7995c173085e3dc042e59ef464c5ed058c3ad863911',
    encrypt: function(value){
        var rsakey = new RSAKey();
        rsakey.setPublic(this.public_key, this.e);
        return rsakey.encrypt(value);
    },
    decrypt: function(ciphertext){
        var rsakey = new RSAKey();
        rsakey.setPrivateEx(this.public_key, this.e, this.private_key.d, this.private_key.p, this.private_key.q, this.private_key.dmp1, this.private_key.dmq1, this.private_key.coeff);
        return rsakey.decrypt(ciphertext);
    },
    ....
};

When I try to decrypt the '$ciphertext_web_safe' value in JavaScript I simply get an empty string. No errors in console log etc..

Is there a problem with the "bin2hex" used in PHP? Should there be some sort of padding etc.. applied before converting the encrypted binary data to hex?

Cheers, Dave

Foi útil?

Solução

My problem was "e" in javascript.

I changed "65537" to "010001" and now I can encrypt server side using the public key and PHP. Phew!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top