Web服务团队编写了这段C#代码,用于公开一些我打算使用的Web服务。 我的密码需要使用这个代码进行加密,这样Web服务就知道如何在其端解密它。
using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(publicKey);
byte[] plainBytes = Encoding.Unicode.GetBytes(clearText);
byte[] encryptedBytes = rsa.Encrypt(plainBytes, false);
return Convert.ToBase64String(encryptedBytes);
}
我正在使用Java调用该Web服务,但现在翻译那个 #C 代码为Java代码存在问题,因为该Web服务无法正确解密我的密码。这是我当前的失败尝试:-
// my clear text password
String clearTextPassword = "XXXXX";
// these values are provided by the web service team
String modulusString = "...";
String publicExponentString = "...";
BigInteger modulus = new BigInteger(1, Base64.decodeBase64(modulusString.getBytes("UTF-8")));
BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(publicExponentString.getBytes("UTF-8")));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String encodedEncryptedPassword = new String(Base64.encodeBase64(cipher.doFinal(clearTextPassword.getBytes("UTF-8"))));
我做错了什么?非常感谢。
2013-08-07 - 更新
我在阅读这个网站时意识到我的模数值和公共指数值不是16进制的。所以,我稍微修改了一下代码,并尝试使用RSA/ECB/PKCS1PADDING
,就像@Dev所提到的那样。
// my clear text password
String clearTextPassword = "XXXXX";
// these are the actual values I get from the web service team
String modulusString = "hm2oRCtP6usJKYpq7o1K20uUuL11j5xRrbV4FCQhn/JeXLT21laKK9901P69YUS3bLo64x8G1PkCfRtjbbZCIaa1Ci/BCQX8nF2kZVfrPyzcmeAkq4wsDthuZ+jPInknzUI3TQPAzdj6gim97E731i6WP0MHFqW6ODeQ6Dsp8pc=";
String publicExponentString = "AQAB";
Base64 base64Encoder = new Base64();
String modulusHex = new String(Hex.encodeHex(modulusString.getBytes("UTF-8")));
String publicExponentHex = new String(Hex.encodeHex(publicExponentString.getBytes("UTF-8")));
BigInteger modulus = new BigInteger(modulusHex, 16);
BigInteger publicExponent = new BigInteger(publicExponentHex);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String encodedEncryptedPassword = new String(base64Encoder.encode(cipher.doFinal(clearTextPassword.getBytes("UTF-8"))));
当我访问Web服务时,出现了这个错误:"The data to be decrypted exceeds the maximum for this modulus of 128 bytes." 看起来明文密码仍然没有被正确加密。
非常感谢任何帮助或建议。谢谢。
2013-08-09 - 解决方案
我在下面发布了我的最终工作解决方案。
Encoding.Unicode.GetBytes(String)
我就会想到UTF-8
,而不是UTF-16LE
,显然这是错误的假设,你能发现这点很好。 - DevmodulusString
和publicExponentString
,请问这两个值在你的代码中是如何工作的? - Panadol Chong