2011-09-07 135 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