繁体   English   中英

使用RSA的解密结果在普通Java和Android中有所不同

[英]Decryption result using RSA differs in plain Java and Android

我对消息进行加密/解密,如下所示:加密字符串-> base64编码字节->序列化字符串->反序列化字符串->解码b64->解密字节。

加密如下所示:

PublicKey pubKey = readPublicKey();
Cipher cipher;
cipher = Cipher.getInstance(CRYPTO_ALG);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData;
cipherData = cipher.doFinal(message.getBytes());
return cipherData;

解密是这样完成的:

PrivateKey pk = readPrivateKey();
Cipher cipher = Cipher.getInstance(CRYPTO_ALG);
cipher.init(Cipher.DECRYPT_MODE, pk);

return new String(cipher.doFinal(data));

密钥的读取方式如下:

ObjectInputStream oin =
   new ObjectInputStream(new BufferedInputStream(is));
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();

RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privKey = fact.generatePrivate(keySpec);

return privKey;

我在这里省略了b64的内容,但是我已经验证了该问题不会影响该代码。

现在发生的是,我实际上得到了正确的答案,但是前面有二进制乱码。 如果我加密“ TESTDATA”,我将得到TESTDATA。 该代码在普通Java中工作正常,但在Android中失败。 有谁知道如何解决这一问题?

编辑:使用RSA / NONE / NoPadding加密/解密似乎没有帮助。 我还在纯JRE中使用org.bouncycastle。

以我的经验,默认值是Java加密中难以发现的错误的巨大且永无止境的来源。 他们可以咬任何人,但它们会捕食初学者。 初学者最有可能选择默认值,因为就其本质而言,它们很困惑并且正在寻求简化。 而且很难发现它们,甚至几乎看不见,因为它们存在。 当您查看String.getBytes()它看起来完全是无辜的。 为什么初学者会怀疑new String(s.getBytes())永远等于s 最糟糕的是,测试似乎表明它是真实的。 仅当您将s.getBytes() byte[]s.getBytes()传输到具有不同平台默认字符集的另一个平台时,您才注意到该错误。

永远不要使用String.getBytes() ,总要使用String.getBytes(Charset) 从不使用的String(byte[])构造,总是使用String(byte [], Charset)构造。 您始终可以使用UTF-8字符集( Charset.forName("UTF-8") )。 我专门使用它。

同样,请始终在Cipher.getInstance(String)工厂方法中指定所有三个组件算法/模式/填充

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM