0

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

neubert
  • 15,947
  • 24
  • 120
  • 212
alee
  • 33
  • 1
  • 3
  • 8
  • Trying random things will lead to nowhere fast, alee, try and learn how to use crypto. PHP is very lenient in that it will accept almost anything as a key.. but an AES key should comprise of 16, 24 or 32 random bytes. Try and view all input to cipher instances as bytes. – Maarten Bodewes Nov 17 '13 at 03:27
  • i am generating random bytes for the AES key(at which i am succeeding) and then trying to convert them to string.....actually after much reading i am starting to think my problem is not understanding the encryption.....it is strings and the one hundred thousand standards.....utf unicode ascii base64.....encode decode... – alee Nov 17 '13 at 14:52

1 Answers1

0

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.

Community
  • 1
  • 1
alee
  • 33
  • 1
  • 3
  • 8
  • in the php code....i have written the unencrypted key to file only to check in android what the generated key was.... it can be commented out once it has been established that the key is translating seamlessly between java and php.... or if needed the key can also be stored in mysql using the standard security practises – alee Nov 18 '13 at 10:53