I am using Swift Sodium on client side as my server is using libsodium to encrypt the data before sharing it with me through API.
Now I have a existing private key and a public key in a String format with me. I want to now decrypt the encrypted data at my end on iOS using Swift.
How do I generate a Sodium Key Pair using the public and private key that I have?
Also Ideally I should use only the private key to decrypt the data. So how do I do that using only private key as String.
My Code for decryption is shown below -
func decryptData(dataString: String) -> String? {
let sodium = Sodium()
let privateKey = sodium?.utils.hex2bin("MY_SECRET_KEY")
let publicKey = sodium?.utils.hex2bin("MY_PUBLIC_KEY")
let message = dataString.data(using: .utf8)!
if let decrypted = sodium?.box.open(anonymousCipherText: message, recipientPublicKey: publicKey!, recipientSecretKey: privateKey!){
// authenticator is valid, decrypted contains the original message
return String(data: decrypted, encoding: String.Encoding.utf8) as String!
}
return nil
}
In the above Code my decrypted String is always empty.
The server is encrypting the data using the below function -
protected function crypt($response)
{
$message = new HiddenString($response);
$repository = \App::make(EncryptionKeysRepository::class);
$enc = $repository->findOneBy(['device' => 'android']);
$dir = $enc->getDevice();
$publicKey = $enc->getPublicKey();
$storage = storage_path();
if(!file_exists($storage."/{$dir}/")) {
mkdir($storage."/{$dir}/");
}
// save key pair to key store
$pubFilename = \tempnam($storage."/{$dir}/", 'pub_key');
file_put_contents($pubFilename, $publicKey);
$public = KeyFactory::loadEncryptionPublicKey($pubFilename);
unlink($pubFilename);
rmdir($storage."/{$dir}/");
$message = Crypto::seal($message, $public);
return $message;
}
Decrypting Logic at server
protected function deCrypt($response)
{
$repository = \App::make(EncryptionKeysRepository::class);
$enc = $repository->findOneBy(['device' => 'android']);
$dir = $enc->getDevice();
$publicKey = $enc->getSecretKey();
$storage = storage_path();
if(!file_exists($storage."/{$dir}/")) {
mkdir($storage."/{$dir}/");
}
// save key pair to key store
$secFilename = \tempnam($storage."/{$dir}/", 'sec_key');
file_put_contents($secFilename, $publicKey);
$secret = KeyFactory::loadEncryptionSecretKey($secFilename);
unlink($secFilename);
rmdir($storage."/{$dir}/");
$res = Crypto::unseal($response, $secret);
$message = $res->getString();
return response()->json(compact('message'));
}
So, server-side, you're apparently using PHP, with a library called Halite.
I'm not very familiar with Halite, but looking at its code, Crypto::seal() uses sealed boxes, so Box::open(anonymousCipherText: Data, recipientPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Data? is the correct method to decrypt this in Swift.
However, Halite also seems to encode the result as a BASE64 string (urlsafe variant).
So, you need to decode this first. Or, and this is going to be way more efficient, do not encode the ciphertext. Unless you have to read them aloud, the keys probably don't need to be encoded either.
Related
How to do I decrypt data using PHP that I have encrypted with using JSEcrypt
Following is how I encrypted my code
async function Encrypt(form = {}) {
const JSEncrypt = (await import("jsencrypt")).default;
let encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
let data = btoa(JSON.stringify(form));
let encrypted = encrypt.encrypt(data);
return encrypted;
}
When I decrypt it using JS, it works fine
async function Decrypt(encrypted) {
const JSEncrypt = (await import("jsencrypt")).default;
let encrypt = new JSEncrypt();
encrypt.setPrivateKey(privateKey);
let decrypted = encrypt.decrypt(encrypted);
return decrypted;
}
How do I do the same decrypt function in PHP ?
This is what I have tried and it does not work
function decrypt($data) {
$privateKey = file_get_contents("../keys/private_key.pem");
$key = openssl_get_privatekey($privateKey);
$data = base64_decode($data);
$result = openssl_private_decrypt($data, $decrypted, $key , OPENSSL_PKCS1_PADDING); //Keeps returning false
if ($result) {
# code...
$decrypted_data = base64_decode($decrypted);
return json_decode($decrypted_data);
}
return "No data";
}
PHP decrypt function returns "No data" because $result keeps returning a false value.
Thank you.
Sample Data that I am using
Blockquote
**Public Key**
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+QJEeRV7zs0Eh3W1/A1L
Bi9Rh8CXO8mdC1GICj3CUfUJ5xHoNGo03XsMZl7rU2szcmYh/T4Iidnr5hkZB/FG
RqmBy9xUA6IKTJANIkhuAGuzhkCXwnKiCjHBHr3HlqBq201BzPqw4+6+TMTmOe1p
DJ6xmy4YALqf5ovZ9HxJ9DcBzzuDgcNBTMcHAskGZexK3C66OJTFeDXqUS8VuYfa
robAuLeH/8LPnFfAKAYvoZQvUM0zvfn/VIJkvPbCeTr5RYvcpCj2t53tSBpaGKRa
EmiIfT3gKUraJDGz4BEtw7skc4Li3vZAt96UA6XoJdglphxwNztA1ZUaovVg2foN
EQIDAQAB
-----END PUBLIC KEY-----
**Private Key**
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD5AkR5FXvOzQSH
dbX8DUsGL1GHwJc7yZ0LUYgKPcJR9QnnEeg0ajTdewxmXutTazNyZiH9PgiJ2evm
GRkH8UZGqYHL3FQDogpMkA0iSG4Aa7OGQJfCcqIKMcEevceWoGrbTUHM+rDj7r5M
xOY57WkMnrGbLhgAup/mi9n0fEn0NwHPO4OBw0FMxwcCyQZl7ErcLro4lMV4NepR
LxW5h9quhsC4t4f/ws+cV8AoBi+hlC9QzTO9+f9UgmS89sJ5OvlFi9ykKPa3ne1I
GloYpFoSaIh9PeApStokMbPgES3DuyRzguLe9kC33pQDpegl2CWmHHA3O0DVlRqi
9WDZ+g0RAgMBAAECggEBAO7twg39E0MnbYUc6XXku2w/0xdTMMnpdor5vHM3N1G0
sb/KauiAUCGEhC1mPp9YaZEHdu2rrD25oKS0yFPaqvf6hdS6oNKrlP5J6pBOt14n
+aaELBokLF9jxk5dAzoAyweKZeztTvYmiurWs6I5r2awjvK7k8R/ThbFcmkpKTzt
9oOvq2QoA+fCeqby63SAvl+KmQs3SCEYYQHAkNhwa6BvYTld6FbzL23BxZs2Zr5F
156X91D4lh1eAtgKW/Qq3O0y+Jgeff1VFYasVEsg26XjzY4cVzYtLjXT0SogKxEy
zQS0xPczkweN+LWNo0TzpKzfCdgqPIc5hxxUK+Aj8AECgYEA/KrkKPO0d+AJQoo3
/9ehf7DLKzvpa1qjdw8GI0w/XVzc1nt2YTziZgH1Rj+f17DqbEZFn8c2dl7Cqk7x
XVW16js92g265avovy745xTZ/GhG/4IvS12cZLggedV33RHXrZ035vy/Ahs/QAOJ
WIkV0u3fcopkIewPnJ/XlxWzCsECgYEA/EsF441w/r1FoYUQ8UqVKsFPsJLKLiGL
FNGyUvhoeI+DpBXAz4ZNYAILHYqOKoV60uZhg73FN0m5ihtgCBT7pnsSTkugDLsv
9zjkogdeRypN4Of/PIKUyylDJCGvIX+YmQ06STuH9H2lbvwg9E0/vElUVL+qC0Bj
UanVmb57JlECgYAVs6PnNI9yoGaLNY37xoyTiB7bNskktGNH7Z1sWLc0kK5TKcWQ
MoeLlW14vCxBfWuVIzAFujmeTyNPN3qZtqvqU25LlVRRN8PE8Abm6i6S9G3sskTX
p1GwgPQhIsmpzkeFHPTZPSo2xxpWqDcayKN8O3wuvV4+X6UzobMFwhJfwQKBgQCA
56AppOH/9hr2rPN8JZxTjRO3ZzjQGylhyMaxJ+TQ/JrJIqgyIC+2hzTAskNzLGIW
EcnvMu3qEswu6U/GsVnmtOkkgfVTq+yVB0eiFduwxsely0OY2itGJl38vw0pM3V3
dc+7DSSo4e296Cq6SCHxhRIGfytVtl9IoVrWxAFOEQKBgFmITpM9StkIHJqd/Lkb
gscOOHRpWd20lPos/n42LoIspz7zgbiEi2saiO+yZZ+xK56PYaGkAIyNvzqOVoKi
HBy3FrbxOc+EGIMemvVPv0rK0Jpz8vdgTmXf+4NbWu7jRCvQCrNbCflWyka/w438
mqlInSoviiAMRu2BcS2cojys
-----END PRIVATE KEY-----
Data Set 1
**Clear Text**
o4XuRo4Im3wkJImjLq96XvODUzR5Y+1GCqViKQqStyoidS8+9aQbLrWFpjhyHuE019YzJLHhuWxWlo7yfR3aebm5kObvq/QBe821dZgnOLtvdeUM4NP8iapjV945DsjRkp9g8vEwH3gGN0p/RrzWvbsF57OZ3eLRFjkFv2TS9PcUVlVHYbxpTjfhskpOQrDJeJJZjnCaRyPOa2VG4k3Y3p7WJzU+oT9DJK2aUscuS8zyDvLHSWvS09KOe/5xu+554Q54QHaLmAUxqu//4EjK+8yDko8Ji3mnmpFD0eyXfO2uMlw8dAUJ4w1++hNr7pr60K4rV47aCP1mh6za9lzmUg==
**Signature String**
7MC7xeKz+wbBTm1uxcKKV6AS3hM5TUS9T2ZWOxnxZNptBvClsoVktdfb8LVCTaDOKU9dopawZhcLl1fPZwHSoeQMhkkI2IRq9eHry4XWmXyDwSTLn+90AIdyxh+RuFrasGvcOmjRc75Eij393eDfl/MHyVeipIZXMUrWmRTgIjekXEffsoVrpuEGygGnltHMINXA+H1EbsFfJL4ok8zm4JhX8NdZSAcM3zeHrsf1DXbDRPOm4rwdZiuR5y4JGiVKXnEqfu3MA+tllQObE0UTngaUVVea5BFAjMYgE58cvYslzUbQAzKJERfABMg+LeBBuWTRPMrA4y+xKf8r2UHUBg==
Signature passes smoothly
Data Set 2
**Clear Text**
34JPmAmu4avmsBDL2A9t3NvC5ljfQgcLNNcEclXbTs+Efi6vj3QZb2eMjIA2uOKgBP3ChVJIAI4Zj9rjq31CmrRVtCMPPX5okgOVOH0wK/v+tScwW87SMWOdGhiBn+HXSYQQO3gpLYczVuD+RHzs5/7FEYSnyfg4aT+UTKDrkIxJFOdbdYUKB9zDeGFDiCqSgphU8qZdVoxAk+yCg5gec+/JnK4hrd209fj1tbE4vzFax9fW+jGscHsIn2Fr6gwpVs2zUAHYn8lbiTfI8ao3TJ2BE7aEkcwsq+SZAsKmWDFnwf7aUtZtr8pCkSvT6A/dMeH1Ib9tWl1A6KpczfHH6g==
**Signature**
x6mXZvdZggPBKxMtmnHIdw2j+7WJgfqfsc8udymJE+Z6tEonQvgr5RKr2OUdLUuYul13G/GCgkm+BpbensfsM7G7IwJenjCJs4FXgtYjLCG3QTLNz2OalgLy1dw1SyRW4XETmsbTZysjxvpaBh0/ggC/Dh2oYFsZYVRGDnFgQTWzmMfMIuq2cDT95MmUyN1wLjRxuiQD4vAowkmf5igJpaw1Bd9+ifT3K7LS9dtmq9bl3n1RKV9I7nWbTgT6qgujOsOwTpYjfuGT2xBuqBvDd+al4FPiMaVSt8oDVr5SLuClXYc9Ky+1OcXEgsjdyHqP7kio58PvitUa++q6m+i5bA==
Signature passes smoothly as well
These are my sample data . Hopefully, it is sufficient enough. Thank you
FULL PHP CODE
Decrypt.php
<?php
function decrypt($data) {
$privateKey = file_get_contents("../keys/private_key.pem");
$key = openssl_get_privatekey($privateKey);
$data = base64_decode($data);
$result = openssl_private_decrypt($data, $decrypted, $key,OPENSSL_PKCS1_OAEP_PADDING);
if ($result) {
# code...
$decrypted_data = base64_decode($decrypted);
return json_decode($decrypted_data);
}
return "No data";
}
?>
VerifySignature.php
<?php
include('./Decrypt.php');
$cert = file_get_contents("../keys/public_key.pem");
/**Run node index.js in terminal to get data & signature */
$data = "o4XuRo4Im3wkJImjLq96XvODUzR5Y+1GCqViKQqStyoidS8+9aQbLrWFpjhyHuE019YzJLHhuWxWlo7yfR3aebm5kObvq/QBe821dZgnOLtvdeUM4NP8iapjV945DsjRkp9g8vEwH3gGN0p/RrzWvbsF57OZ3eLRFjkFv2TS9PcUVlVHYbxpTjfhskpOQrDJeJJZjnCaRyPOa2VG4k3Y3p7WJzU+oT9DJK2aUscuS8zyDvLHSWvS09KOe/5xu+554Q54QHaLmAUxqu//4EjK+8yDko8Ji3mnmpFD0eyXfO2uMlw8dAUJ4w1++hNr7pr60K4rV47aCP1mh6za9lzmUg==";
$signature = "7MC7xeKz+wbBTm1uxcKKV6AS3hM5TUS9T2ZWOxnxZNptBvClsoVktdfb8LVCTaDOKU9dopawZhcLl1fPZwHSoeQMhkkI2IRq9eHry4XWmXyDwSTLn+90AIdyxh+RuFrasGvcOmjRc75Eij393eDfl/MHyVeipIZXMUrWmRTgIjekXEffsoVrpuEGygGnltHMINXA+H1EbsFfJL4ok8zm4JhX8NdZSAcM3zeHrsf1DXbDRPOm4rwdZiuR5y4JGiVKXnEqfu3MA+tllQObE0UTngaUVVea5BFAjMYgE58cvYslzUbQAzKJERfABMg+LeBBuWTRPMrA4y+xKf8r2UHUBg==";
$pubkeyid = openssl_pkey_get_public($cert);
//verify signature
$result = openssl_verify($data, base64_decode($signature), $pubkeyid,OPENSSL_ALGO_SHA256);
// $result = openssl_verify($data, $signature, $pubkeyid,OPENSSL_ALGO_SHA256);
if ($result == 1) {
# code...
var_dump("Valid Signature");
$decrypted = decrypt($data);
} else {
var_dump("Invalid Signature");
}
?>
Others have suggested to just lean on HTTPS, a few things to bare in mind:
HTTPS encrypts the communication between the client and the server using SSL/TLS protocols. This protects all data, including query strings in URLs, from being tampered with or intercepted while in transit.
Query strings in URLs are sent as regular text as part of the request, but when HTTPS is used, the entire request, including the query strings, are encrypted, making them secure during the transmission.
Now to your problem...
Assuming your public key is definitely married to your private key.
OpenSSL functions are typically used to decrypt payloads from OpenSSL functions, whilst both OpenSSL and JSEncrypt use the RSA algorithm, it's fair to say that their implementation may be different.
You could try using phpseclib
composer require phpseclib/phpseclib
<?php
use phpseclib3\Crypt\PublicKeyLoader;
function decrypt($encrypted)
{
$privateKey = file_get_contents('/path/to/your/private.key');
/** #var \phpseclib3\Crypt\RSA\PrivateKey $loader */
$loader = PublicKeyLoader::loadPrivateKey($privateKey);
$decrypted = $loader->decrypt(base64_decode($encrypted));
return json_decode(base64_decode($decrypted), true);
}
Disclaimer: Code above is untested
I need to encrypt user and password with AES-256-CBC and PKCS7 padding to connect to a .NET server application that it is not mine.
Firstly, I got the public server key using Diffie-Hellman algorithm, following the instructions on this site:
https://doc.developer.milestonesys.com/mipsdkmobile/index.html?base=content_0.html&tree=tree_home.html
The code to get the public key from server is:
private const DH_PRIME = 'F488FD584E49DBCD20B49DE49107366B336C380D451D0F7C88B31C7C5B2D8EF6F3C923C043F0A55B188D8EBB558CB85D38D334FD7C175743A31D186CDE33212CB52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92F78C7';
private const DH_GENERATOR = '02';
$privateKey = gmp_init(uniqid(), 32);
$publicKey = gmp_powm(self::DH_GENERATOR, $privateKey, base_convert( self::DH_PRIME, 16,10));
Once I got the key, so it is working great here, I must compute the server key with my private key, previously decoding base64 server key, and converting it from binary to hexadecimal:
// Decode server public returned key (encoded in base 64)
$serverPKBase64Decoded = base64_decode($apiResponse['response']['Command']['OutputParams']['Param']['7']['#attributes']['Value']);
$serverPublicKey16 = bin2hex($serverPKBase64Decoded);
// Calculate shared key
$prime = gmp_init(self::DH_PRIME,16);
$serverPk = gmp_init($serverPublicKey, 16);
$localPk = gmp_init($localPrivateKey,32);
$sharedKey = gmp_powm($serverPk, $localPk, $prime);
// Get shared key as hexadecimal value
$sharedKeyHex = gmp_strval($sharedKey, 16);
Now, it comes the part to get the initialization vector (iv) and the key to encrypt the username and password:
$iv = substr($sharedKeyHex,0,16);
$key = strlen($sharedKeyHex)-32,32);
// Encrypt username and password
$encryptedUsername = base64_encode(openssl_encrypt($username,$cipher,$key,OPENSSL_RAW_DATA,$iv));
$encryptedPassword = base64_encode(openssl_encrypt($password,$cipher,$key,OPENSSL_RAW_DATA,$iv));
When I send the data and got the response, it throws an error 16 with the text "Incorrect public key".
Our provider's SDK gives examples (on JS with CryptoJS) where the login process is equivalent. Please, could you confirm the code is equal in JS than in PHP:
JS Code:
/**
* Encode a string using client and server public keys
*
* #param str string String to encode
* #access public
* #return string Base64 encoded encrypted string
*/
this.encodeString = function(str) {
var secretString = this._sharedKey || this.getSharedKey().substring(0, 96);
var key = CryptoJS.enc.Hex.parse(secretString.substring(32, 96));
var iv = CryptoJS.enc.Hex.parse( secretString.substring(0,32) );
var params = { 'iv': iv };
if (XPMobileSDKSettings.defaultEncryptionPadding && CryptoJS.pad[XPMobileSDKSettings.defaultEncryptionPadding]) {
params.padding = CryptoJS.pad[XPMobileSDKSettings.defaultEncryptionPadding];
}
return CryptoJS.AES.encrypt(str, key, params).ciphertext.toString(CryptoJS.enc.Base64);
};
I have tested with many PADDINGS but I am not able to get it working. Any ideas why it is not working or what I must change to get it working?
You should prefix your username & password with your own public key, otherwise the server cannot calculate the shared key.
Im trying to decrypt a text sent from the server to an android application.
On PHP, I have the following:
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$key = "-----BEGIN PUBLIC KEY-----\n" . ($PublicKey)
. '-----END PUBLIC KEY-----';
$rsa->loadKey($key);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
$imageEncrypt = base64_encode($rsa->encrypt($base64));
The encoding and the encryption work well.
When I send the encrypted text to android, i cannot decrypt. I used the code:
public static String decryptString(String alias,String cipherText) {
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
// RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}
String finalText = new String(bytes, 0, bytes.length, "UTF-8");
return finalText;
//decryptedText.setText(finalText);
} catch (Exception e) {
Toast.makeText(context, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
Log.e("DecryptStringTAG", Log.getStackTraceString(e));
}
return "EMPTY";
}
The error is:
java.io.IOException: Error while finalizing cipher
Caused by: javax.crypto.IllegalBlockSizeException
The odd thing is that when i try to send from PHP a message like "Hello", android decrypts it successfully. But when i send the encrypted image, I get the stated error.
I've been struggling to find the error.
Any help?
Thanks
RSA asymmetric key encryption which is what public key encryption uses, that is RSA is essentially public key encryption. If you must use public/private key pair encryption the answer is hybrid encryption, similar to what SSL does.
Create a random symmetric key use it to encrypt the data with AES. Then encrypt the symmetric key with the RSA public key.
On decryption first decrypt the symmetric key with the RSA private key and use that to decrypt the data with the symmetric AES.
If you are looking for secure encryption you really need to get someone who is a domain expert to at least design and vett the implementation. Security is very hard to get right, if it isn't right is provides no security.
i need some help for solve my problem.
Problem :
I want to encrypt a number (A) with public RSA Key from Android platform and then decrypt it on PHP Server with the private key.
On each platform, i can encrypt and decrypt data (it works well), but when the PHP script try to decrypt data encrypted from ANDROID, it doesn't work !!
Problem is not from HTTP Transmission, because I try to decrypt directly a generating Encryption from ANDROID (coded in Base64) and it not work at all ...
Findhere after my PHP Code for decrypt data :
class MyEncryption
{
public $privkey = '';
public $pubkey = '';
public function __construct(){
}
public function initialize() {
$fp=fopen("./encryption/asasap_public.pub","r");
$temp=fread($fp,8192);
fclose($fp);
$this->pubkey = openssl_pkey_get_public($temp);
$fp=fopen("./encryption/asasap.pem","r");
$temp=fread($fp,8192);
fclose($fp);
$this->privkey = openssl_get_privatekey($temp,'');
}
public function encrypt($data)
{
if (openssl_public_encrypt($data, $encrypted, $this->pubkey))
$data = base64_encode($encrypted);
else
throw new Exception('Unable to encrypt data. Perhaps it is bigger than the key size?');
return $data;
}
public function decrypt($data)
{
if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey))
$data = $decrypted;
else
$data = '';
return $data;
}
public function hex2bin($hexdata) {
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
}
And i use this class like here :
$enc = new MyEncryption();
$enc->initialize();
$data_1 = 'K27booXr0zZK4BQlI45MIPJJjPPkpCCPELGvoK/wKYUwShIWE6szlZtrmV83C5eBIrT/3lxWTH3+IOA+5mefurVUvXmQIV7fXEHNHLphyM6L9gQsMAGZMCroPjWKvJM59OMS/d5dwwhiRgzVarxXSKpxBYhEYWJTu7nRJ+bZKjumeoqnCSpmntIiV+tRYgkYflOU6j2QlesjO5tzj/TL6n7vHSO/O1qafJkzHcv8Kn2hTy+IH7QXm7z5vtjXOucHkvBm1xWORXdifh+ChyVvP16dSEmCaCAH6KqtA4viX/HwRFEi4mIWaYSIQk74NdcnQOpFcTgEu2nDwtHaBMqahw==';
$data_2 = $enc->decrypt($data_1);
Here data_1 is initialized from the encrypt data (A=5) from android with the RSA Public Key (note : decrypt works well on Android), but after decryption in PHP, i get empty String ...
------------------------------------------ UPDATE -------
Please find here after the code for ANDROID part :
public byte[] encryptRSA(final InputStream publicKeyFile, String in) throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException {
byte[] encodedKey = new byte[5000];
publicKeyFile.read(encodedKey);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pkPublic = kf.generatePublic(publicKeySpec);
// Encrypt
Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
pkCipher.init(Cipher.ENCRYPT_MODE, pkPublic);
return pkCipher.doFinal(in.getBytes());
}
After encrypt data, i convert the byte[] into Base64 (Base64.encodeToString(input, Base64.DEFAULT)).
For the certificate, i use RSA 2048 Bits convert into DER Format for Android.
------------------------------------------ SOLUTION -------
Error are in following Lines :
byte[] encodedKey = new byte[5000];
publicKeyFile.read(encodedKey);
We must read exactely the Public Key :
byte[] encodedKey = new byte[/*lenght of file*/];
publicKeyFile.read(encodedKey);
There are a lot of places this can go wrong:
You are passing 5000 bytes to X509EncodedKeySpec, most of which are 0. Are you sure you are getting the proper public key?
How long is the in String?
String.getBytes() uses the platform default encoding and may have unintended results. Use getBytes("ASCII") or getBytes("UTF-8").
Generally, you should just use SSL, and don't try to implement asymmetric encryption yourself.
i try de decrypt my file ,but i have this message
Warning: mcrypt_cbc() [function.mcrypt-cbc]: Size of key is too large
for this algorithm in
/Applications/XAMPP/xamppfiles/htdocs/test/test.php on line 32
<?php
$key = md5("Test");
//fonction decode
function decode($pass_coder)
{
$pass_str = mcrypt_ecb(MCRYPT_TripleDES,$key, $pass_coder, MCRYPT_DECRYPT);
return $pass_str;
}
echo (decode($pass_coder));
>
i use this function to encrypt my file
public void Encrypt(XmlDocument doc, string rootTag, string password)
{
// Transform password to MD5 hash value
ASCIIEncoding enc = new ASCIIEncoding();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] md5val = md5.ComputeHash(enc.GetBytes(password));
// Create key and use MD5 hash value as key
TripleDES key = TripleDESCryptoServiceProvider.Create();
key.Key = md5val;
// Encrypt data
EncryptedXml ec = new EncryptedXml(doc);
ArrayList list = new ArrayList();
foreach (XmlElement el in doc.GetElementsByTagName(rootTag))
{
byte[] data = ec.EncryptData(el, key, false);
EncryptedData ed = new EncryptedData();
ed.Type = EncryptedXml.XmlEncElementUrl;
ed.EncryptionMethod = new EncryptionMethod(EncryptedXml
.XmlEncTripleDESUrl);
ed.CipherData = new CipherData();
ed.CipherData.CipherValue = data;
list.Add(new object[] { el, ed });
}
// Write encrypted data to XML document
foreach (object[] obj in list)
EncryptedXml.ReplaceElement((XmlElement)obj[0], (
EncryptedData)obj[1], false);
}
Maybe I've missed your problem entirely, but what I suspect you are trying to do, is not possible. You cannot decrypt something that has been hashed with MD5. You can compare and eventually come to the conclusion that string_xxx == string_yyy if the MD5 hashes match when using the same salt ...