2011-09-07 111 views
1

我需要一些幫助來解決我的問題。RSA Android加密/ RSA PHP解密

問題: 我想用來自Android平臺的公共RSA密鑰加密數字(A),然後用私鑰在PHP服務器上解密它。 在每個平臺上,我可以對數據進行加密和解密(效果很好),但是當PHP腳本試圖解密從ANDROID加密的數據時,它不起作用!

問題是不是從HTTP傳輸,因爲我嘗試直接解密從ANDROID發電加密(編碼爲Base64),它不是在所有的工作......

Findhere後,我的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); 

這裏_1是從Android上的加密數據(A = 5)與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(輸入,Base64.DEFAULT))。

對於證書,我使用RSA 2048位轉換爲Android的DER格式。

------------------------------------------ SOLUTION --- ----

錯誤是下面幾行:

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

我們必須閱讀exactely公鑰:

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

那麼Android代碼呢? –

回答

1

有很多地方這可能出問題:

  1. 您正在傳遞5000個字節到X509EncodedKeySpec,其中大部分爲0.您確定您獲得了正確的公鑰嗎?
  2. in字符串有多長?
  3. String.getBytes()使用平臺默認編碼,並可能有意想不到的結果。使用getBytes("ASCII")getBytes("UTF-8")

通常,您應該只使用SSL,而不要嘗試自己實施非對稱加密。

+0

好吧,您有權利,我將讀取緩衝區更改爲KEY的長度並在PHP頁面上解密。謝謝 – user932356