Question

i am using android to create a key pair, i use http post to send the public key to a wamp server mysql data base using a php script.

after successfully receiving the key, the php scripts encrypts a string using the key and encoding it with base43, the sripts echos a json object to android.....where i decode using base64 and then use the private key to decrypt the text and then base64encode it again to view it.

php

$rawKey = $_POST['rawKey'];
$publicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . chunk_split($rawKey) .  
"-----END RSA PUBLIC KEY-----";
$rsa = new Crypt_RSA();
$rsa->loadKey($publicKey); // public key
$AESKeyString = "some text";
$AESKeyString = $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($AESKeyString);
$ciphertext = base64_encode($ciphertext);
$response = array('' => $ciphertext);
echo json_encode($response);

java

public String Decrypt(String encryptedKey) {
    Cipher cipher = null;
    try {
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} try {
    cipher.init(Cipher.DECRYPT_MODE, privKey);
} catch (InvalidKeyException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
byte[] cipherData = null;
try {
    cipherData = cipher.doFinal(Base64.decode(encryptedKey, Base64.NO_WRAP));
} catch (IllegalBlockSizeException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (BadPaddingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
    String cipherString = Base64.encodeToString(cipherData, Base64.NO_WRAP);
    Log.d("SecCom", cipherString);
    return cipherString;
}

the problem WAS that although there were no errors in decryption the text was always garbage....however this garbage was unique and same for a give plaintext....that is to say "hello world" in java would always translate to "n;lk@;la" and only changing the plain text would change the decrypted garbage.

i looked at numerous examples on stackoverflow and this seemed to work for them and purely out of some gut feeling i added a base64 decode to the php string before encrypting it

$AESKeyString = base64_decode("some text");

and viola this solved the problem except for the fact that now i get origional string in java except that all the spaces are removed..... and the last character is replaced by g==

that is "some text" appears as "sometexg=="

i have tried numerous texts but this is constant through all no spaces and last character replaced by g==

in my final php script i will be generating random bytes for aes, encrypting them and then encoding them to send to java. please keep this in mind in the solution that you provide me.....

also why did adding base64.decode in php was necessary for me yet for others it worked just out of the box

thanks

Was it helpful?

Solution

as i mentioned in my comments.... my problem was not understanding the String and encoding part and how it tranlates to java.....

well i gave it a go, did a bit of reading and rewrote the php side and it worked in the first attempt.....

.... here is a full working php code....the java code does not need to be changed....i have also commented it

php //get the posted public key $pumpumString = $_POST['pumpum'];

    //format public key in CRYPT format
    $publicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . chunk_split($pumpumString) . 
    "-----END RSA PUBLIC KEY-----";

    //initialise Algorithm
    $rsa = new Crypt_RSA();
    $rsa->loadKey($publicKey); // public key
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

    //generate new AES Session Key
    $AESKey = rand_sha1(32); //a custom created function

    $AESKeyDecoded = base64_decode($AESKey);

    //encrypt AES Session Key
    $ciphertext = $rsa->encrypt($AESKeyDecoded);

    //base 64 encode it for transfer over internet
    $ciphertextEncoded = base64_encode($ciphertext);

    //prepare array for sending to client
    $response = array('plum' => $ciphertextEncoded);

    //write the encoded and decoded AES Session Key to file for comparison
    $file = fopen('key.txt', 'w');
    fwrite($file, "\n". $AESKey);

    //echo JSON
    echo json_encode($response);

one of the things that puzzled me earlier was why i needed to base64 decode my plaintext before encryption....well what i have been able to figure out is that, php probably uses ASCII to store strings. since in java i am using a base64_encode to get the decrypted string from the decrypted byte array.....i need to first decode my ascii plaintext string to regenerate it in java......(i might have worded that a bit non-coherently...please feel free to reword it.)

if u feel that i have come to the wrong conclusion or something can be bettered please let me know, i am marking this as solved....

also i had asked for a way to generate a random aes key.....below is the function i used to do it.....courtesy https://stackoverflow.com/a/637322/2208279

php

function rand_sha1($length) {
    $max = ceil($length / 40);
    $random = '';
    for ($i = 0; $i < $max; $i ++) {
        $random .= sha1(microtime(true).mt_rand(10000,90000));
    }
return substr($random, 0, $length);
}

i am using a aes256 so i have used 32 as the argument to this function....modify it to 16 for 128

thanks....hope this helps someone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top