Android RSA解密(失败)/服务器端加密(openssl_public_encrypt)

时间:2013-07-23 19:19:33

标签: android encryption openssl rsa

我正在尝试使用设备上生成的RSA密钥解密我的Android应用程序中的字符串。加密是由php服务完成的,使用我的应用程序提供的public rsa密钥。我的问题是解密,但失败了。

我正在做以下事情:

  • 在Android上生成KeyPair(使用KeyPairGenerator.getInstance(“RSA”)) - >确定

  • 在使用Base64.encode(pubKey.getEncoded())编码“base64”后,两个密钥(公共和私有)都保存到文件中,并且与私钥相同。 - >确定

  • 当我呼叫我的网络服务时,我将我的公钥(在基数64中)传递给一个post变量 - >确定

  • Web服务(php服务)使用openssl_public_encrypt函数使用公钥加密短字符串。加密的字符串将转换为base64。 - >看来没问题,该功能不会返回FALSE。

  • 应用程序检索服务的结果并对其进行解码(Base64.decode()) - >好的(我已经检查过,收到的字节与openssl_public_encrypt()函数生成的字节匹配)

  • 最后一件事是解密这个字符串,我正在做以下事情: - >不行

    Cipher cipher = Cipher.getInstance(“RSA”);

    cipher.init(Cipher.DECRYPT_MODE,privateKey);

    byte [] decryptedBytes = cipher.doFinal(cryptedBytes);

    String decryptedString = new String(decryptedBytes);

    的System.out.println(decryptedString);

解密的结果与原始字符串不匹配。

我遗失了什么?

1 个答案:

答案 0 :(得分:10)

OpenSSL默认使用padding = OPENSSL_PKCS1_PADDING。因此,要在两侧使用相同的填充机制,您应该使用Cipher.getInstance("RSA/ECB/PKCS1Padding")。这也是您可以在Java SE中使用的。

请注意,依赖于加密中的默认操作模式非常危险。许多实现具有不同的默认值,并且这些默认值很难查找。因此,请始终尝试完全指定要使用的算法/模式。

您可以尝试其他RSA填充模式,但请注意 - 不幸的是 - Android已经禁用了他们调整的Bouncy Castle源代码中的大量算法和别名。


[编辑]这是一个陈旧的答案,现在强烈建议使用OAEP填充,或者使用RSA-KEM进行混合密码术。