mardi 22 septembre 2015

phpseclib RSA encrypt C++ Decrypt

I'm currently trying to implement a serial generation and checking system, the serials are generated in PHP and encrypted using RSA private key then passed to my c++ app for decryption using the public key.

The issue I'm having is that openssl in the c++ app is throwing the error "error:0407006A:lib(4):func(112):reason(106)" when attempting to decrypt the serial. Googling the error seems to suggest that there's something wrong with my cipher text but I've no idea what. Decrypting the serial on the website using the methods below works fine.

I'm assuming phpseclib is encrypting them differently somehow but as far as I can see they should be compatible and share the exact same keys and padding.

This is my PHP class

<?
set_time_limit(0);

include 'Crypt/RSA.php';

class RSA
{
    public $key_length;
    public $private_exp;
    public $public_exp;
    public $modulus;
    private $rsa_crypt;

    function RSA($key_len)
    {
        $this->rsa_crypt = new Crypt_RSA(); 
        $this->key_length = $key_len;   
        $this->rsa_crypt->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
    }

    function GenerateKeys()
    {
        $this->rsa_crypt->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
        $this->rsa_crypt->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS8);

        extract($this->rsa_crypt->createKey($this->key_length));

        $this->private_exp = $privatekey;
        $this->modulus = $publickey;

        return true;
    }

    function Encrypt($plain_data)
    {
        $this->rsa_crypt->loadKey($this->private_exp); // private key   
        // divide plain data into chunks
        $data_len = strlen($plain_data);
        $block_len = (int) ($this->key_length / 8) - 11;
        $curr_pos = 0;
        $enc_data = '';
        while ($curr_pos < $data_len) 
        {
            $tmp = substr($plain_data, $curr_pos, $block_len);
            $enc_data .= $this->rsa_crypt->encrypt($tmp);
            $curr_pos += $block_len;
        }

        return $enc_data;
    }

    function Decrypt($enc_data)
    {
        $this->rsa_crypt->loadKey($this->modulus); // public key    
        // divide encrypted data into chunks
        $data_len = strlen($enc_data);
        $block_len = (int) $this->key_length / 8;
        $curr_pos = 0;
        $dec_data = '';
        while ($curr_pos < $data_len) 
        {
            $tmp = substr($enc_data, $curr_pos, $block_len);
            $dec_data .= $this->rsa_crypt->decrypt($tmp);
            $curr_pos += $block_len;
        }

        return $dec_data;
    }
}

?>

And my C++ decryption class

int public_decrypt(unsigned char * enc_data, int data_len, unsigned char * key, unsigned char *decrypted)
{
    RSA * rsa = createRSA(key, 1);
    int keySize = RSA_size(rsa);
    int currPos = 0;
    int  result;
    char errbuff[256] {0};
    while (currPos < data_len)
    {
        result = RSA_public_decrypt(keySize, enc_data, decrypted, rsa, RSA_PKCS1_PADDING);
        if (result == -1)
        {
            int err = ERR_get_error();
            ERR_error_string_n(err, errbuff, sizeof(errbuff));
        }
        currPos += keySize;
    }

    return result;
}

Aucun commentaire:

Enregistrer un commentaire