目前我试图用php中的rsa加密,用Android应用程序生成的公钥然后再在android app中解密。
我在android中生成密钥的代码是:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
使用这些键,我可以很好地解密和解密。 pub键如下所示:
OpenSSLRSAPublicKey{modulus=9ee9f82dd8429d9fa7f091c1d375b9c289bcf2c39ec57e175a2998b4bdd083465ef0fe6c7955c821b7e883929d017a9164a60290f1622f664a72096f5d2ffda7c7825c3d657c2d13d177445fa6cdd5d68b96346006a96040f5b09baae56d0c3efeaa77d57602f69018f5cefd60cb5c71b6b6f8a4b0472e8740367266917d8c13,publicExponent=10001}
在php中取模数和指数,用phpseclib 1.0创建加密字符串
$rsa = new Crypt_RSA();
// $rsa->createKey();
$m = "9ee9f82dd8429d9fa7f091c1d375b9c289bcf2c39ec57e175a2998b4bdd083465ef0fe6c7955c821b7e883929d017a9164a60290f1622f664a72096f5d2ffda7c7825c3d657c2d13d177445fa6cdd5d68b96346006a96040f5b09baae56d0c3efeaa77d57602f69018f5cefd60cb5c71b6b6f8a4b0472e8740367266917d8c13";
$e = "10001";
$data = "hallo";
$modulus = new Math_BigInteger($m, 16);
$exponent = new Math_BigInteger($e, 16);
$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$messageEncrypt = $rsa->encrypt($data);
再次在Android中,即时加载密钥,然后像这样解密:
Cipher cipher1 = Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher1.doFinal(encrypted.getBytes());
String decrypted = new String(decryptedBytes);
我总是得到一个错误的解密明文或"引起:java.lang.ArrayIndexOutOfBoundsException:RSA块的数据太多"来自Android的错误消息。
我的想法:问题是编码传输。那个php输出一个不同的编码版本,就像java一样。所以我尝试了很多不同的方法。我试图将输出转换为String / bin / hex / byte。然后将其传输,使用套接字或直接在代码中复制+粘贴。将其从十六进制/ bin转换回字节[]并尝试解码。什么都行不通......
任何人都有解决方案吗?
答案 0 :(得分:0)
由于您没有使用phpseclib指定加密模式,这意味着您正在使用(更安全且不常见的)OAEP加密模式。我的猜测是Java默认使用PKCS1加密($rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
)。
也就是说,使用OAEP模式和您正在使用的密钥(1024位密钥; 128字节),限制为86字节。 PKCS1模式的限制是117个字节。
phpseclib 1.0 / 2.0可能不会出错,因为phpseclib会尝试用户友好,并将字符串拆分为最大大小的块,并将分别加密每个块。 Java不太可能这样做。