2

这是一个字符串:

String msg="dpbqNszFN2cpmtlzPi3myV9M1ctlkSIQD95ue+T+9rz13T+Pe/aLZ8Pd5geI+PhEM/b0UeRS1cAzKybQsKICTBhh3ke5Jjw6BHWGESJWBnUT54lAlTvzkgOxpQ5stBh2cPPSn3KLyKmXifr8ClbV5s1k3Gy5C7HitA5KLw7hRxAmIGSWQG7PaiLNEVRbgicNfJ7Ic7VIdGA/UA51vK8mpywIR2YQUDPv30ThGq4DuclaJ3X4aVWVj8VYChcfM+82sViVU8HO3DF9CCU4EIADNET503olxiDZBp7WMYmJvWq0KhhZXkLSY3QFmcSMX6IThtdKKCcZp6hu3TtC+7aP7Q==";

所以字节数组是

[1] => 100     [2] => 112     [3] => 98     [4] => 113     [5] => 78     [6] => 115     [7] => 122 ..

应该解码

[我使用 PHPbase64_encode()编码为上述形式并base64_decode()获得此输出]

[1] => 118     [2] => 150     [3] => 234     [4] => 54     [5] => 204     [6] => 197      7] => 55     ...

但我面临的问题是(在 android 中,使用Base64.decode(String))它被解码为:

[118, -106, -22, 54, -52, -59, 55, 103, 41, -102, -39, 115, 62, 45, -26, -55, 95, 76, -43, -53, 101, -111, 34, 16, 15, -34, 110, 123, -28, -2, -10, -68, -11, -35, 63, -113, 123, -10, -117, 103, -61, -35, -26, 7, -120, -8, -8, 68, 51, -10, -12, 81, -28, 82, -43, -64, 51, 43, 38, -48, -80, -94, 2, 76, 24, 97, -34, 71, -71, 38, 60, 58, 4, 117, -122, 17, 34, 86, 6, 117, 19, -25, -119, 64, -107, 59, -13, -110, 3, -79, -91, 14, 108, -76, 24, 118, 112, -13, -46, -97, 114, -117, -56, -87, -105, -119, -6, -4, 10, 86, -43, -26, -51, 100, -36, 108, -71, 11, -79, -30, -76, 14, 74, 47, 14, -31, 71, 16, 38, 32, 100, -106, 64, 110, -49, 106, 34, -51, 17, 84, 91, -126, 39, 13, 124, -98, -56, 115, -75, 72, 116, 96, 63, 80, 14, 117, -68, -81, 38, -89, 44, 8, 71, 102, 16, 80, 51, -17, -33, 68, -31, 26, -82, 3, -71, -55, 90, 39, 117, -8, 105, 85, -107, -113, -59, 88, 10, 23, 31, 51, -17, 54, -79, 88, -107, 83, -63, -50, -36, 49, 125, 8, 37, 56, 16, -128, 3, 52, 68, -7, -45, 122, 37, -58, 32, -39, 6, -98, -42, 49, -119, -119, -67, 106, -76, 42, 24, 89, 94, 66, -46, 99, 116, 5, -103, -60, -116, 95, -94, 19, -122, -41, 74, 40, 39, 25, -89, -88, 110, -35, 59, 66, -5, -74, -113, -19]

如您所见,某些字符(虽然不可读)没有被正确解码。 编辑(2):字节在 java 中签名,在 PHP 中未签名。感谢@Jon 和@Tony 清除了这个想法。但是错误仍然存​​在于我的代码中。

编辑(1):

代码段:

KeyFactory fact = KeyFactory.getInstance("RSA");
BigInteger e=new BigInteger("65537");
BigInteger n=new BigInteger("B7AC0C8F738305F8BDDF93EE25655A70FBDF9F074640C159E36914C227BE1E50A615A25E6706EBA08FB79216F02279420ED4C9DA310778601F6A3233EDADE2FF3775D29E5302C4FCB9E7879D9F3C814AE8F42759148D91CDB23E528241AE2E44F6DE9D4334494C103886B2333D5833EFEABD76205B8F4897BB908E71697A10F6494EBFB0392A831575F64672E0F915A88F46F7FC03E7F94EB56A8A3296840095CB53787EE6E71D4C297108EA5CDD31BD37B1C0A55A8B5FA78F88FC82AEF3C2C80C0FC2CC97A1AEC74ACE44F4AC1B111B727311DA4D1447899A15BA292BCA4E7E864DF55CCB903CD4109874AD475393E7F24FC60E2D7B88E9B4FB57FA54A9B817",16);
RSAPublicKeySpec keySpec=new RSAPublicKeySpec(n,e);
PublicKey pubKey = (PublicKey) fact.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey );
String msg="dpbqNszFN2cpmtlzPi3myV9M1ctlkSIQD95ue+T+9rz13T+Pe/aLZ8Pd5geI+PhEM/b0UeRS1cAzKybQsKICTBhh3ke5Jjw6BHWGESJWBnUT54lAlTvzkgOxpQ5stBh2cPPSn3KLyKmXifr8ClbV5s1k3Gy5C7HitA5KLw7hRxAmIGSWQG7PaiLNEVRbgicNfJ7Ic7VIdGA/UA51vK8mpywIR2YQUDPv30ThGq4DuclaJ3X4aVWVj8VYChcfM+82sViVU8HO3DF9CCU4EIADNET503olxiDZBp7WMYmJvWq0KhhZXkLSY3QFmcSMX6IThtdKKCcZp6hu3TtC+7aP7Q==";
byte[] bytes=msg.getBytes("UTF-8");
byte[] enc_bytes= Base64.decode(bytes,Base64.DEFAULT);
byte[]  dt = cipher.doFinal(enc_bytes);   
String code=new String(dt,"UTF-8");
System.out.println(code);

密码解密字符串出来为(在第二个 system.out )

05-10 21:05:27.501: I/System.out(11809): �ќ2`��H&��'Va�x�m��0G�����V�T�����)^����/|���BG,f_r    fK�B7?�a��n������Jl�y�yL���}��΂Ճ������JZj�+�|�-#ș%u�1�z�c�G��nl�5����HELLO HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 H

Base64_encoded & 签名数据是“HELLO HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 HI1 H”


[解决了]

非常感谢@JonSkeet。

cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");删除了所有以它为前缀的垃圾数据。

4

3 回答 3

6

在我看来一切都很好——你只需要记住字节是用 Java 签名的。因此,Java 中的值 -106 对应于无符号值 150。一旦记住这一点,我想您会发现 PHP 中的所有值都对应于 Java 中的值。

请注意,您应该区分字节字符。所以当你说:

如您所见,某些字符(虽然不可读)没有被正确解码。

实际上是指一些字节......并且没有“可读”字节这样的概念。

编辑:我看不到任何迹象表明您实际上已经解密了数据。

您正在使用平台默认编码将 base64 解码的仍然加密的结果转换为文本:

String tmpr=new String(baser);

你不应该这样做 - 你应该使用baser密文来解密。

根本不清楚tmp你传递的价值doFinal来自哪里......

于 2012-05-10T15:27:12.390 回答
1

你的问题是标志之一。第一个样本“应该”将输出字节视为 8 位无符号。Android 版本将它们视为有符号字节。

你的代码真的失败了吗?

编辑

cipher.final()似乎是为了完成解密而设计的。你是cipher.update()先打电话的吗?请参阅此处的示例,并查找update(...)stackoverflow.com/questions/3150830/android-encryption

这是Android Cipher 文档,为您提供方便。

于 2012-05-10T15:28:29.363 回答
-2

Try this on your byte array

byte[] bytes = Base64.decode(data, Base64.DEFAULT);
String string = new String(bytes, "UTF-8");
于 2012-05-10T15:26:14.263 回答