我需要一些帮助来解决我的问题。
问题: 我想用来自Android平台的公共RSA密钥加密一个数字(A),然后用私钥在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是从带有RSA公钥的android的加密数据(A = 5)初始化的(注意:解密在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());
}
加密数据后,我将byte []转换为Base64(Base64.encodeToString(输入,Base64.DEFAULT))。
对于证书,我使用RSA 2048 Bits转换为Android格式的DER格式。
------------------------------------------解决方案---- ---
错误在以下行中:
byte[] encodedKey = new byte[5000];
publicKeyFile.read(encodedKey);
我们必须彻底阅读公钥:
byte[] encodedKey = new byte[/*lenght of file*/];
publicKeyFile.read(encodedKey);
答案 0 :(得分:1)
有很多地方可能出错:
X509EncodedKeySpec
,其中大部分都是0.您确定要获得正确的公钥吗?in
字符串有多长? String.getBytes()
使用平台默认编码,可能会产生意想不到的结果。使用getBytes("ASCII")
或getBytes("UTF-8")
。 通常,您应该只使用SSL,而不要尝试自己实施非对称加密。