Convert RSA PEM to XML codeigniter framework - php

Is there a way to convert RSA PEM Public key to XML without using 3rd party library.
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEDtIRT57TJAfmub2RsIM32jdo
8ijsds/u1fpY6hwtkC01/LFJkNTXqSwvpaO5tp86o0SlzBHdF0WxPtsKqdc8F7kQ
uHm7hUTLX0zPGRdGCsy9q/PIGlVGAFTBSVXl+grmGGZuS1CHI13L/oulBGENQOxO
8r6D1RyPjt6z0BAndQIDAQAB
-----END PUBLIC KEY-----
output should be in this format
<RSAKeyValue><Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6WjubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
i tried to implemented this
$publicKey = -----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEDtIRT57TJAfmub2RsIM32jdo
8ijsds/u1fpY6hwtkC01/LFJkNTXqSwvpaO5tp86o0SlzBHdF0WxPtsKqdc8F7kQ
uHm7hUTLX0zPGRdGCsy9q/PIGlVGAFTBSVXl+grmGGZuS1CHI13L/oulBGENQOxO
8r6D1RyPjt6z0BAndQIDAQAB
-----END PUBLIC KEY-----;
$this->load->dbutil();
$this->output->set_content_type('text/xml');
$dom = new DOMDocument("1.0");
$root = $dom->createElement("publicKey");
$dom->appendChild($root);
$marker = $dom->createElement("marker");
$root->appendChild($marker);
echo $dom->saveXML();
can anyone know the answer.
Thanks in advance

Cryptography is complex math and 99% of us are not capable to understand the core. So it's not just a simple XML.
Do not try to implement your own solutions to an already known and solved problem.
Use a proven library
For example phpseclib
use phpseclib3\Crypt\RSA;
class Home extends BaseController
{
public function index()
{
$key = RSA::load(file_get_contents('key.pem'));
echo $key->toString("XML"); //this gives you Modulus/Exponent XML string
}
}

Related

Why are pem2der and der2pem not inverses?

In the supplementary comments for PHP's OpenSSL functions there's this snippet
function pem2der($pem_data) {
$begin = "CERTIFICATE-----";
$end = "-----END";
$pem_data = substr($pem_data, strpos($pem_data, $begin)+strlen($begin));
$pem_data = substr($pem_data, 0, strpos($pem_data, $end));
$der = base64_decode($pem_data);
return $der;
}
function der2pem($der_data) {
$pem = chunk_split(base64_encode($der_data), 64, "\n");
$pem = "-----BEGIN CERTIFICATE-----\n".$pem."-----END CERTIFICATE-----\n";
return $pem;
}
These functions aren't inverses. My test code:
$priv_key = ...;
print $priv; // dev data, of course
print der2pem (pem2der ($priv));
Prints
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAAS... (etc)
then
-----BEGIN CERTIFICATE-----
TEKEYMIIJQwIBADANBgkqhkiG9w0BAQEFA... (etc)
Note the second one has a TEKEY prefix. In hex that's 4c4284 which doesn't look significant.
Where did this come from?
These functions are only designed to handle certificates, not private keys. The reason the result is wrong is because the pem2der function is looking for the start of a certificate (CERTIFICATE----- from -----BEGIN CERTIFICATE-----). You're trying to decode a key starting with -----BEGIN PRIVATE KEY-----. The "TE KEY" part of the result comes from here: "-----BEGIN PRIVATE KEY-----" and is a result of the functions not handling that header so the substr calls return the wrong result.
In theory, the functions should be very easy to modify to process private key files though.

Export OpenSSL public key to file

How can I export only the public key to a file(.pem) with PHP?
Of course it is possible to export the whole certificate and a private key but I can't find a solution to export a public key.
The file should look like
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArDjwWcPjZRQpiMRsG1fG
kudSYEHnSR57dKUoK+qIc++YZSCWG/q460LrNtQ/EBx6ZdJJnhBk4EwY0snb7TEr
pH5efU2BuCygO3f78DozMxNvvHFFfZ1uw4hobBMSKLKtVcJKmh7r7dvgXtKWdqJf
sUmr2V3LDXTF3r6G5NEorGC4crcSByAvyPatUKRR5t6kAuU8pnWrHnDo+GoSjHy2
vvaUuds6FxHMieFXKrnN8dk6VPpV2PEwzSAk9Ofbq3oZxkIhVGTHjgFPF9tIx3Vu
yo+S4KCP6sxmEt1/p4B5VsCsRU4STbA5jC8qK9vJ1YhMD6tK5FWreaDiWL3wBjf5
xwIDAQAB
-----END PUBLIC KEY-----
That's the solution. Thanks to https://www.virendrachandak.com/techtalk/encryption-using-php-openssl/
// Generate the public key for the private key
$key = openssl_pkey_get_details($privateKey); // $privateKey is created with openssl_pkey_new()
// Save the public key in public.pem file
file_put_contents('public.pem', $key['key']);

Votifier PHP Encryption

I've been trying to add votifier functionality to my site but so far, without any luck at all.
My problem is that the encryption using the openssl_public_encrypt returns an empty response.
Here's my code: http://pastebin.com/wakjcxSF
I call it like this:
$vote = new Vote(USERNAME, SERVERIP, SERVERPORT, VOTIFIERKEY);
$vote->castVote();
The output of the print_r:
0
VOTE Something test 127.0.0.1 1376050280
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiRda9+W9mXLz1Mvc4hXMo rea2NPPJVgbQCypwpgIUK0Q7vQ2sK+Om2yCyTtwIvdOCAa1Uh+cX2Drs3xHkPutw/ rkTiFEWWQ3ol3jxMm+5BXUSESSK+P26nr7JvFddnOdVM1FFVCwFXYmYIwigeXK3lO qrOLFdxVEbpG5wEcNPOVIqq1RKfKQIFGvYfIVpRCaj3yMRlSK4S1jQtlqMy5Tnva+ xqaFjEHN2QJRwLecmkPnGsWicEfoc+khV64/06YKg5Becqx69sS+snY8SM1E/atZk b/eqm165A7Awzw3e9Fl2Uk4F7kUwrRGZDjzu6knr6Vr13slXDxzEKd33xv8/QIDAQ AB -----END PUBLIC KEY-----
Original public key:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiRda9+W9mXLz1Mvc4hXMorea2NPPJVgbQCypwpgIUK0Q7vQ2sK+Om2yCyTtwIvdOCAa1Uh+cX2Drs3xHkPutw/rkTiFEWWQ3ol3jxMm+5BXUSESSK+P26nr7JvFddnOdVM1FFVCwFXYmYIwigeXK3lOqrOLFdxVEbpG5wEcNPOVIqq1RKfKQIFGvYfIVpRCaj3yMRlSK4S1jQtlqMy5Tnva+xqaFjEHN2QJRwLecmkPnGsWicEfoc+khV64/06YKg5Becqx69sS+snY8SM1E/atZkb/eqm165A7Awzw3e9Fl2Uk4F7kUwrRGZDjzu6knr6Vr13slXDxzEKd33xv8/QIDAQAB
I used this tutorial: http://topg.org/php_votifier.
I tried to look around on google but the problems was invalid key problems. Result:
google (com)/search?q=Votifier+PHP+Encryption&oq=Votifier+PHP+Encryption&aqs=chrome.0.69i59j69i60j69i62l2.6301j0&sourceid=chrome&ie=UTF-8#bav=on.2,or.r_cp.r_qf.&fp=917b53cc1ec39b52&q=Votifier+PHP+Encryption
Found this too: teamavolition (com)/topic/14380-solved-php-rsa-encryptions-votifier/
Best Regards,
- ImThatPedoBear
That's sorta a "naked" RSA public key. OpenSSL only works with public keys that are in an X.509 cert.
My recommendation would be to use phpseclib's Crypt_RSA. eg.
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey('...'); // public key
$plaintext = '...';
//$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$ciphertext = $rsa->encrypt($plaintext);

Trouble with RSA using phpseclib in PHP

I'm trying to use the RSA implementation in phpseclib, I thought it would be easier to do the code once in a function and re-use the function.
When I've tried texting the code I get a error saying "decryption error"
Testing also made me realise that the ciphertext was different every time the code ran, so I'm clearly doing something wrong there!
The code for the functions is:
require_once "Crypt/RSA.php";
require_once "Crypt/AES.php";
//Function for encrypting with RSA
function rsa_encrypt($string, $public_key)
{
//Create an instance of the RSA cypher and load the key into it
$cipher = new Crypt_RSA();
$cipher->loadKey($public_key);
//Set the encryption mode
$cipher->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//Return the encrypted version
return base64_encode($cipher->encrypt($string));
}
//Function for decrypting with RSA
function rsa_decrypt($string, $private_key)
{
//Create an instance of the RSA cypher and load the key into it
$cipher = new Crypt_RSA();
$cipher->loadKey($private_key);
//Set the encryption mode
$cipher->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//Return the decrypted version
return $cipher->decrypt($string);
}
I've tried to test it using the following:
(The keys are just for testing so that's why its hardcoded).
It is in here that everytime the code is run that the value of $ciphertext changes everytime
//Private key
$private_key = "-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCU+1bLfPmcY7qrF/dTbAtuJlv4R/FVc1WEH9HKU0jQjX/n/db9vz/x0i3te/bK LNEcwUhBu+PWPnOt/qVURG9BUT6RsCRFUn0CyGiUKoy45o9K/mJAHmbrNtrUB6ckrYLF75Y50nUN sBVHUDw8yQymmiOBT1gc/KM5s1xTz44LMwIDAQABAoGAGsiMtAyFu23ac0PdvOuhqm3O/vXAF0Ki zxwBVURfxM6LfiOOcRPe5RSKGTW+Cl7AQVEmMlsa/LtBhLhQ9LNQ5L/4oTmRhCGiZZEmccAdjKsx yMeaxkp+ZHvMxMKQNDgYg1CXqrCrpwwUuMUlA26tfxZ3xSFtFyDTaV9mgDQ1IGECQQCkX9Tum7D1 vQTwbhbYnu7eC4eUOaZeGWSEs2csK7U6vfZ3BzUZW/0tPqcSpQqcNxMtY9TiUsNRj1uM6jX3byp7 AkEA6Ab+wvOTNRtES77OAYG9gHGZZ+iXjQJ/6Z7JehN4p41UbDIf9nNUOLUPL9z5V1uOYnl1CWoo Cw95cdhKXxEAqQJBAIU5Or6tp250ZdVslM27ewSyuY9UblfkIsk/EscFIdzbbDAqwkmsefW6yvTc mU3lgYCPYlKRG8c19tCuX1ENY5MCQAz37x9YW975Ai01ofAFn2DheJCNOINCI4IcROiU1AaRaKmP d6fftFJjFFE5iZovXNr2LOt0yn4rxD7vtuBvY9kCQGyty6YCB6qaD7qXPMhLrLbGajAIWd6ETgxv frK/BJu+buPfDky/g1FhI5R9iMtL1xH0JYLJlaVocU+xSeA9DkY= -----END RSA PRIVATE KEY-----";
//Public key
$public_key = "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCU+1bLfPmcY7qrF/dTbAtuJlv4R/FVc1WEH9HK U0jQjX/n/db9vz/x0i3te/bKLNEcwUhBu+PWPnOt/qVURG9BUT6RsCRFUn0CyGiUKoy45o9K/mJA HmbrNtrUB6ckrYLF75Y50nUNsBVHUDw8yQymmiOBT1gc/KM5s1xTz44LMwIDAQAB -----END PUBLIC KEY-----";
//Test out the rsa encryption functions
$plaintext = "This is some plaintext to encrypt";
$ciphertext = rsa_encrypt($plaintext, $public_key);
$decipheredtext = rsa_decrypt($ciphertext, $private_key);
//Echo out results
echo sprintf("<h4>Plaintext for RSA encryption:</h4><p>%s</p><h4>After encryption:</h4><p>%s</p><h4>After decryption:</h4><p>%s</p>", $plaintext, $ciphertext, $decipheredtext);
EDIT:
Sample output is:
Plaintext for RSA encryption:
This is some plaintext we will encrypt
After encryption:
‘˜!ˆ_枦WýF¦E×9&ùš!´jéÓb÷á劀É7J+۪߯׎È㩨ɣ#(÷)ÃX„)÷O‘­Ë±N#Øv«ÓÌPƒ¹—Âî!a¢¦a&Á½Á˜ö‰ºŠCðJ«vW{uAåoOÂXäÞ#÷ï`agÏ:OŒ
After decryption:
//Nothing is returned, it is blank here
I think GigaWatt's answer is the correct one. As for this:
Testing also made me realise that the ciphertext was different every
time the code ran, so I'm clearly doing something wrong there!
PKCS#1 padding adds random bytes so the ciphertext's will always be different. The PKCS#1 algorithm however knows when the plaintext ends and the random bytes begin so it's able to separate the two and return you the result you're wanting.
EDIT: I got it to work after I replaced the spaces in your keys with new lines. eg.
$private_key = "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCU+1bLfPmcY7qrF/dTbAtuJlv4R/FVc1WEH9HKU0jQjX/n/db9vz/x0i3te/bK
LNEcwUhBu+PWPnOt/qVURG9BUT6RsCRFUn0CyGiUKoy45o9K/mJAHmbrNtrUB6ckrYLF75Y50nUN
sBVHUDw8yQymmiOBT1gc/KM5s1xTz44LMwIDAQABAoGAGsiMtAyFu23ac0PdvOuhqm3O/vXAF0Ki
zxwBVURfxM6LfiOOcRPe5RSKGTW+Cl7AQVEmMlsa/LtBhLhQ9LNQ5L/4oTmRhCGiZZEmccAdjKsx
yMeaxkp+ZHvMxMKQNDgYg1CXqrCrpwwUuMUlA26tfxZ3xSFtFyDTaV9mgDQ1IGECQQCkX9Tum7D1
vQTwbhbYnu7eC4eUOaZeGWSEs2csK7U6vfZ3BzUZW/0tPqcSpQqcNxMtY9TiUsNRj1uM6jX3byp7
AkEA6Ab+wvOTNRtES77OAYG9gHGZZ+iXjQJ/6Z7JehN4p41UbDIf9nNUOLUPL9z5V1uOYnl1CWoo
Cw95cdhKXxEAqQJBAIU5Or6tp250ZdVslM27ewSyuY9UblfkIsk/EscFIdzbbDAqwkmsefW6yvTc
mU3lgYCPYlKRG8c19tCuX1ENY5MCQAz37x9YW975Ai01ofAFn2DheJCNOINCI4IcROiU1AaRaKmP
d6fftFJjFFE5iZovXNr2LOt0yn4rxD7vtuBvY9kCQGyty6YCB6qaD7qXPMhLrLbGajAIWd6ETgxv
frK/BJu+buPfDky/g1FhI5R9iMtL1xH0JYLJlaVocU+xSeA9DkY=
-----END RSA PRIVATE KEY-----";
//Public key
$public_key = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCU+1bLfPmcY7qrF/dTbAtuJlv4R/FVc1WEH9HK
U0jQjX/n/db9vz/x0i3te/bKLNEcwUhBu+PWPnOt/qVURG9BUT6RsCRFUn0CyGiUKoy45o9K/mJA
HmbrNtrUB6ckrYLF75Y50nUNsBVHUDw8yQymmiOBT1gc/KM5s1xTz44LMwIDAQAB
-----END PUBLIC KEY-----";

How to generate a DER/PEM certificate from public exponent and modulus of RSA?

As we know, a public key consists of a public exponent and a modulus.
My questions is:
How to generate a DER/PEM certificate from public exponent and modulus of RSA?
Thank you very much in advance.
With a public exponent and modulus the best you could hope to do is to get something like this:
-----BEGIN PUBLIC KEY-----
MIGGAoGAfHlcdrcuOK6C02rbGR3SgV/ZJ2wnTiFBguh5FHduoB6LcZz49LIC/KcIiH/TckK8GxQd
oJ7wHCPBpNiumrlC6caj/C8jO/HZ3cb12Wuk4gUuJq1lg5+HTv4KRJ9pFeEFQqS6X+BTztY+EoRx
uc8MlLXS4PUeouwd9Ios2K0Y5/sCASU=
-----END PUBLIC KEY-----
That said, usually DER/PEM files are used to hold private keys and you're not going to be able to get the private exponent when all you have is the public one. If, however, the above is what you're looking for, let me know and I can post further instructions on how to get it from the modulus / public exponent!
edit: Here's how I'd do it:
<?php
include('Crypt/RSA.php');
$modulus = new Math_BigInteger($modulusBinaryString, 256);
$exponent = new Math_BigInteger($exponentBinaryString, 256);
$rsa = new Crypt_RSA();
$rsa->modulus = $modulus;
$rsa->exponent = $exponent;
$rsa->publicExponent = $exponent;
$rsa->k = strlen($rsa->modulus->toBytes());
echo $rsa->getPublicKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
?>
I'm using phpseclib, a pure PHP RSA implementation.

Categories