how to encrypt word document using publickey in php - php

I have a problem, I want to encrypt word docs(which have only 10 Kb) using public key, and it must decrypt with private key.
I already created key pair using phpseclib library.
http://phpseclib.sourceforge.net/crypt/examples.html
and I can encrypt and decrypt string using that library. but I don't know how to encrypt file using key pair.
is there any method for this.(or using file_get_contents)
thanks for all
<?php
//create word docx using phpdocx
require("phpDocx.php");
$phpdocx = new phpdocx("word_temp\loan_app_temp.docx");
//assign
$upfno='999';
$loanid_db='1234';
$phpdocx->assign("#upfno#","$upfno");
$phpdocx->assign("#loanid#","$loanid_db");
$phpdocx->assign("#fullname#","$name");
$phpdocx->assign("#initials#","$initials");
$phpdocx->save("word_gen\loan_docs\la_".$upfno."_".$loanid_db.".docx"); // sucessfully created.
// create key pair using phpseclib
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include('phpseclib/Crypt/RSA.php');
$rsa = new Crypt_RSA();
//$rsa->setPassword('layanthi#123');
extract($rsa->createKey());
//echo "$privatekey<br />$publickey";
echo $privatekeydata=$privatekey;
echo '<br />';
echo $pubkey=$publickey; //key pair genarated - ok
//encryption using pubkey - commented snippet from phpseclib
$file="word_gen\loan_docs\la_".$upfno."_".$loanid_db.".docx";
$message=file_get_contents($file);
function rsa_encrypt($key, $message) {
$rsa = new Crypt_RSA();
$rsa->loadKey($key);
$encrypted = base64_encode($rsa->encrypt($message));
return $encrypted;
}
echo $encrypt_file=rsa_encrypt($pubkey, $message);
//from here i want to save encryptted file to encrypt folder like
//$savepath="encrypt\la_".$upfno."_".$loanid_db.".docx"; but i dont know how to do that
//Deryption using phpseclib function is here - but how to use it for above encryption
function rsa_decrypt($key, $package) {
$rsa = new Crypt_RSA();
$rsa->loadKey($key);
$decrypted = $rsa->decrypt(base64_decode($package));
return $decrypted;
}

echo $encrypt_file=rsa_encrypt($pubkey, $message);
$savepath="word_gen\encrypt\la_".$upfno."_".$loanid_db.".docx";
file_put_contents($savepath, $encrypt_file);
//Deryption using phpseclib function is here - but how to use it for above encryption
function rsa_decrypt($key, $package) {
$rsa = new Crypt_RSA();
$rsa->loadKey($key);
$decrypted = $rsa->decrypt(base64_decode($package));
return $decrypted;
}
//get encrypt file
$encfile="word_gen\encrypt\la_".$upfno."_".$loanid_db.".docx";
$epackage=file_get_contents($encfile);
echo $decryptfile= rsa_decrypt($privatekeydata, $epackage);
$savepath_de="word_gen\decrypt\la_".$upfno."_".$loanid_db.".docx";
file_put_contents($savepath_de, $encrypt_file);
?>

Related

PHP RSA Enryption Always Returns "AAAAAAA"

I'm trying to encrypt a message using phpseclib. Below is the method that encrypts it:
function RSAEncrypt($data, $publicKey)
{
$rsa = new \Crypt_RSA();
$rsa->loadKey($publicKey);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$encryptedData = $rsa->encrypt($data);
$encodedData = base64_encode($encryptedData);
return $encodedData;
}
the code that encrypt message
$client_key = 123456789;
$random_str = rand();
$aes_password = $client_key.'-'.$random_str;
$public_key = file_get_contents('keys/public.xml');
$ecrypted_password = RSAEncrypt($aes_password, $public_key);
but no matter the message the $aes_password that i passed , the $ecrypted_password output is always
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE= ◀"
I tried to decrypt it using the private key to see if its valid anyways but i always gets Decryption Error so i figured maybe the error is with the encryption

Is it Possible to migrate from PEAR Crypt to PHPSecLib RSA?

We migrated to PHPSecLib a while ago, but did not migrate our legacy data that was encrypted by the old PEAR\Crypt_RSA library. We've reached a point where we need to migrate that data into PHPSecLib's RSA format. While investigating this, I came across this old forum thread. I attempted to apply the suggestion in the response, but could not get it to successfully decrypt our data. It's not erroring out or anything, it just appears to still be encrypted or encoded. We're running PHPSecLib 2.0.6 currently, and I suspect the instructions were for 1.x.
Here's a roughed out version of my adapted decryption flow (based off the forum thread):
$rsaDecryptor = new RSA();
// The Private Key is encrypted based off a password
$mc = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($mc), MCRYPT_DEV_URANDOM);
$keySize = mcrypt_enc_get_key_size($mc);
$key = substr($rsaDecryptor->password, 0, $keySize);
mcrypt_generic_init($mc, $key, $iv);
$privateKey = mdecrypt_generic($mc, base64_decode($privateKey));
mcrypt_generic_deinit($mc);
mcrypt_module_close($mc);
list($privateKeyModulus, $privateKeyExponent) = unserialize(base64_decode($privateKey));
$privateKeyExponent = new BigInteger(strrev($privateKeyExponent), 256);
$privateKeyModulus = new BigInteger(strrev($privateKeyModulus), 256);
$rsaDecryptor->modulus = $privateKeyModulus;
$rsaDecryptor->exponent = $privateKeyExponent;
$rsaDecryptor->publicExponent = $privateKeyExponent;
$rsaDecryptor->k = strlen($this->decRSA->modulus->toBytes());
// ciphertext is the raw encrypted string created by PEAR\Crypt_RSA
$value = base64_decode($ciphertext);
$value = new BigInteger($value, 256);
$value = $rsaDecryptor->_exponentiate($value)->toBytes();
$value = substr($value, 1);
Bugs In PEAR's Crypt_RSA
So I was playing around with this. There's a bug in PEAR's Crypt_RSA (latest version) that might prevent this from working at all. The following code demonstrates:
$key_pair = new Crypt_RSA_KeyPair(1024);
$privkey = $key_pair->getPrivateKey();
$pubkey = $key_pair->getPublicKey();
$a = $privkey->toString();
$b = $pubkey->toString();
echo $a == $b ? 'same' : 'different';
You'd expect $a and $b to be different, wouldn't you? Well they're not. This is because RSA/KeyPair.php does this:
$this->_public_key = &$obj;
...
$this->_private_key = &$obj;
If you remove the ampersands it works correctly but they're in the code by default.
It looks like this is an unresolved issue as of https://pear.php.net/bugs/bug.php?id=15900
Maybe it behaves differently on PHP4 but I have no idea.
Decrypting Data
Assuming the above bug isn't an issue for you then the following worked for me (using phpseclib 2.0):
function loadKey($key) // for keys genereated with $key->toString() vs $key->toPEMString()
{
if (!($key = base64_decode($key))) {
return false;
}
if (!($key = unserialize($key))) {
return false;
}
list($modulus, $exponent) = $key;
$modulus = new BigInteger(strrev($modulus), 256);
$exponent = new BigInteger(strrev($exponent), 256);
$rsa = new RSA();
$rsa->loadKey(compact('modulus', 'exponent'));
return $rsa;
}
function decrypt($key, $ciphertext)
{
if (!($ciphertext = base64_decode($ciphertext))) {
return false;
}
$key->setEncryptionMode(RSA::ENCRYPTION_NONE);
$ciphertext = strrev($ciphertext);
$plaintext = $key->decrypt($ciphertext);
$plaintext = strrev($plaintext);
$plaintext = substr($plaintext, 0, strpos($plaintext, "\0"));
return $plaintext[strlen($plaintext) - 1] == "\1" ?
substr($plaintext, 0, -1) : false;
}
$key = loadKey($private_key);
$plaintext = decrypt($key, $ciphertext);
echo $plaintext;
Private Keys Generated with toPEMString()
With PEAR's Crypt_RSA you can generate private keys an alternative way:
$key_pair->toPEMString();
This method works without code changes. If you used this approach to generate your private keys the private key starts off with -----BEGIN RSA PRIVATE KEY-----. If this is the case then you don't need to use the loadKey function I wrote. You can do this instead:
$key = new RSA();
$key->loadKey('...');
$plaintext = decrypt($key, $ciphertext);
echo $plaintext;

encrypt/decrypt with Android and PHP

Sorry for this question. I've read all the previous questions, but my code still not work.
Thanks in advance to anyone that will help me in understanding where is the problem.
In android I use this code for reading the public key and produce the encrypted text:
public static PublicKey getPublicKeyFromString(String stringKey) throws Exception {
byte[] keyBytes = stringKey.getBytes();
byte[] decode = Base64.decode(keyBytes, Base64.DEFAULT);
KeyFactory fact = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decode);
return (PublicKey) fact.generatePublic(x509KeySpec);
}
public static String RSAEncrypt(final String plain, final PublicKey publicKey)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
byte[] encryptedBytes;
Cipher cipher;
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
encryptedBytes = cipher.doFinal(plain.getBytes());
return Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
}
//I call these functions in this manner.
private final String pubKeyString =
//"-----BEGIN PUBLIC KEY-----" +
"MIG..." +
"...";
//"-----END PUBLIC KEY-----"
PublicKey pubKey = RSAFunctions.getPublicKeyFromString(pubKeyString);
String encData = RSAFunctions.RSAEncrypt("prova", pubKey);
The publickey.php and privatekey.php file are generated in php with this code:
<?php
include('./Crypt/RSA.php');
$rsa = new Crypt_RSA();
extract($rsa->createKey()); // == $rsa->createKey(1024) where 1024 is the key size
$File1 = "./privatekey.php";
$Handle = fopen($File1, 'w');
fwrite($Handle, "<?php \$privatekey=\"" . $privatekey . "\"?>");
fclose($Handle);
$File2 = "./publickey.php";
$Handle = fopen($File2, 'w');
fwrite($Handle, "<?php \$publickey=\"" . $publickey . "\"?>");
fclose($Handle);
?>
In php I use this code for decrypt data:
<?php
include('Crypt/RSA.php');
require('privatekey.php');
$rsa = new Crypt_RSA();
$rsa->loadKey($privatekey); // private key
$base64_string = $_GET["data"];
$base64_string = str_replace(' ', '+', $base64_string);
$ciphertext = base64_decode( $base64_string );
//$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$plaintext = $rsa->decrypt($ciphertext);
echo $plaintext;
?>
I've also made a php crypt script for testing my decrypt php function. This is the code of my encrypt.php:
<?php
include('Crypt/RSA.php');
require('publickey.php');
$rsa = new Crypt_RSA();
$rsa->loadKey($publickey); // public key
$plaintext = $_GET["data"];
//$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$ciphertext = $rsa->encrypt($plaintext);
echo base64_encode( $ciphertext );
?>
I've no problem when encrypt and decrypt text using only php, but if I use the encrypted data made with android app, php give me an error in decrypting.
Thanks for the attention.
In your php there is :
CRYPT_RSA_ENCRYPTION_PKCS1
but when you create your Cipher object on Android you omit the mode and padding
cipher = Cipher.getInstance("RSA");
you should try something like
Cipher c = Cipher.getInstance("AES/CBC/PKCS1Padding");
ref :
http://developer.android.com/reference/javax/crypto/Cipher.html

how make signature by private key and check it by public key in php

I have a RSA private key and a RSA public key.
both rsa keys are in xml version ( <RSAKeyValue><Modulus>.... );
I need to make a PKCS8 signature from private key and test it by publik key in php
I used this snippet for making signature:
$content = "test string";
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents("private.txt"));
$pem_format = $rsa->getPrivateKey();
$pvk_res = openssl_get_privatekey($pem_format);
$sig = '';
openssl_sign($content , $sig, $pvk_res, OPENSSL_ALGO_SHA1);
$signature = base64_encode($sig);
is this right way for making signature ??
now how use public key to test accuracy of signature ??
PKCS8 concerns key formats - not signatures.
Also, I see you're using phpseclib to convert the key to pem and then using openssl. Why not just use phpseclib for everything? At that point you could use this example:
http://phpseclib.sourceforge.net/rsa/examples.html#sign,sign2
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
//$rsa->setPassword('password');
$rsa->loadKey('...'); // private key
$plaintext = '...';
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$signature = $rsa->sign($plaintext);
$rsa->loadKey('...'); // public key
echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
?>

I can't get RSA encryption to work with my database

I'm trying to use phpseclib to encrypt PII before inserting data into my mySQL database.
I can seem to encrypt something, and put it into a database, but when I recall it, I can't decrypt it.
Any Ideas what I'm doing wrong?
<?php
$con=mysqli_connect("localhost","XXXXXXX","XXXXXXX","XXXXXXX");
include('phpseclib/Crypt/RSA.php');
$secret= 'Hello World';
$pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCunhp5XEEptnE/+jhfdTF1ryjr 756tUJs26RTKgVa/6isdO+SzTdHRvsOqle8Ze58Y9Qj8goVGkcsxrSHr+nEWcN6O oQK+e1Inux5PDwVOE9kiWbjDN4hs41+d6ZgdN6l8h4bhPeAVgQoS2F4a2TKMyLY5 dyzwj7RK98mLwbfaNwIDAQAB";
$rsa = new Crypt_RSA();
$rsa->loadkey($pubkey);
$name = "apersonalname";
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($secret);
$storeme = base64_encode($ciphertext);
echo $storeme;
mysqli_query($con, "INSERT INTO `enctest`(`Name`, `SecretMessage`) VALUES ('$name','$storeme')");
$findsecret = mysqli_query($con, "SELECT * FROM `enctest` WHERE `Name`='$name'");
while($row = mysqli_fetch_array($findsecret))
{
$sm = $row['SecretMessage'];
};
$return = base64_decode($sm);
$rsa = new Crypt_RSA();
$rsa->loadKey('MIICXQIBAAKBgQCunhp5XEEptnE/+jhfdTF1ryjr756tUJs26RTKgVa/6isdO+Sz TdHRvsOqle8Ze58Y9Qj8goVGkcsxrSHr+nEWcN6OoQK+e1Inux5PDwVOE9kiWbjD N4hs41+d6ZgdN6l8h4bhPeAVgQoS2F4a2TKMyLY5dyzwj7RK98mLwbfaNwIDAQAB AoGBAJBl1/ix7IUFBOPmFIYD0LHD9nAdCDfEZ4Zh+rp3eHhdueeD5tzLpo3vVbkU IdQN4YPu5c6CVJoF6GUdCecthCOvQtHtIZq3Gc3Bg6e7lnc3TXek1rBvIooexwj7 wqi+kHOxDZIo271CHccZCOmimBIPfA2x+LpdEa41ftJpxdM5AkEA4JbhbCaCGTQe ra9vGs/GIa61Rhemp8Ei/CrQwE8IgeMTFEnWj7qz23851uwPcdXUV4KvN/JtsFnr m2wyd501KwJBAMcKDO/XDgHuZc9X06lp0rkTqH6ToP7iZFhGvQV7TPt0AsJ2ew8z BKXAAwAE1aVWmt1V2OfX2JgXYUJGjX9eASUCQQDIMzc25QzL0r4WLXBpAhWoKMjG dobEu1GoX7I9+zWmMvjq+PceoFt7qmmwwDT0UJw8de4jfSNyNHXl0gkavzSJAkAO bQ4O/BlJzouWgZkXuFHLlD8sHWsXzjTTqRzeHtevifMBQTEeIuZ9VPNitvb9Ks/C pww3kY9jRp6H/TEYQCn5AkBp/tVM5fh7zp3D0K22oj/0N4aDMPMJ+PiaIMVz8ATj sqX4tZ0dDJ1tInz7uiDM1WH/8JV48kI6EQ8V2ekct51T');
echo $rsa->decrypt($return);
mysqli_close($con);
?>
You're creating two Crypt_RSA objects but only on the first one are you doing $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);. Do it on the second one, too, and you should be good to go!

Categories