I’m trying to port the following php functionality over to perl:
public function loadKey($mod, $exp, $type = 'public')
{
$rsa = new Crypt_RSA();
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
$rsa->setHash('sha256');
$rsa->modulus = new Math_BigInteger(Magicsig::base64_url_decode($mod), 256);
$rsa->k = strlen($rsa->modulus->toBytes());
$rsa->exponent = new Math_BigInteger(Magicsig::base64_url_decode($exp), 256);
// snip...
}
I need to convert a string in the form (“RSA.$mod.$exp.$private_exp”):
RSA.mVgY8RN6URBTstndvmUUPb4UZTdwvwmddSKE5z_jvKUEK6yk1u3rrC9yN8k6FilGj9K0eeUPe2hf4Pj-5CmHww==.AQAB.Lgy_yL3hsLBngkFdDw1Jy9TmSRMiH6yihYetQ8jy-jZXdsZXd8V5ub3kuBHHk4M39i3TduIkcrjcsiWQb77D8Q==
…to a Crypt::RSA object. I’ve split out the components so I have $mod, $exp, and $private_exp, but the perl Crypt::RSA API doesn’t seem to have a way to explicitly set.
Worked out on IRC, documenting it here for the rest of the world: it’s completely undocumented but
Crypt::RSA::Keydoes have methods calledn,e, anddthat correspond to the modulus, the public exponent, and the private exponent. Modulo bugs in the check function (which is supposed to work ifpandqare unavailable butnis, but actually doesn’t), it’s possible to create a working key with those methods.We solved the problem together by creating a subclass of
Crypt::RSA::Key::Privatewith a factory method that decodes the base64 encoding (using MIME::Base64::URLSafe) and the additional binary encoding (using Math::BigInt->from_hex andunpack "H*") and then sets those three private members, and theCrypt::RSAmodules were able to accept it as a Key.