RSA Android Encrypt / RSA PHP Расшифровать - PullRequest
1 голос
/ 07 сентября 2011

Мне нужна помощь для решения моей проблемы.

Проблема: Я хочу зашифровать число (A) с помощью открытого ключа RSA с платформы Android, а затем расшифровать его на PHP-сервере с помощью закрытого ключа.На каждой платформе я могу зашифровать и расшифровать данные (это работает хорошо), но когда скрипт PHP пытается расшифровать данные, зашифрованные с помощью ANDROID, это не работает !!

Проблема не в передаче HTTP, потому чтоЯ пытаюсь расшифровать непосредственно генерирующее шифрование из ANDROID (закодировано в Base64), и оно не работает вообще ...

Найдите здесь после моего кода PHP для расшифровки данных:

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;
}
}

используйте этот класс как здесь:

$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);

Здесь data_1 инициализируется из зашифрованных данных (A = 5) с Android с открытым ключом RSA (примечание: расшифровка хорошо работает на Android), но после расшифровки в PHP, я получаю пустую строку ...

------------------------------------------ ОБНОВЛЕНИЕ -------

Пожалуйста, найдите здесь после кода для части ANDROID:

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());
}

После шифрования данных я преобразую байт [] вBase64 (Base64.encodeToString (input, Base64.DEFAULT)).

Для сертификата я использую биты RSA 2048 для преобразования в формат DER для Android.

------------------------------------------ РЕШЕНИЕ -------

Ошибка в следующих строках:

byte[] encodedKey = new byte[5000];
publicKeyFile.read(encodedKey);

Мы должны точно прочитать Открытый ключ:

byte[] encodedKey = new byte[/*lenght of file*/];
publicKeyFile.read(encodedKey);

1 Ответ

1 голос
/ 07 сентября 2011

Есть много мест, где это может пойти не так:

  1. Вы передаете 5000 байтов X509EncodedKeySpec, большинство из которых равны 0. Вы уверены, что получаете правильный открытый ключ?
  2. Какова длина строки in?
  3. String.getBytes() использует кодировку платформы по умолчанию и может привести к непредвиденным результатам.Используйте getBytes("ASCII") или getBytes("UTF-8").

Как правило, вы должны просто использовать SSL и не пытаться самостоятельно внедрять асимметричное шифрование.

...