c# - 将 C# RSACryptoServiceProvider 转换为 JAVA 代码

标签 c# java security encryption rsa

我收到了由 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 - 更新

我正在阅读this website我意识到我的模值和公共(public)指数值不是十六进制的。因此,我稍微修改了我的代码,并尝试使用@Dev提到的RSA/ECB/PKCS1PADDING

// 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"))));

当我访问网络服务时,我收到此错误:“要解密的数据超出了 128 字节模数的最大值。” 看来明文密码仍然不是正确加密。

非常感谢任何帮助或建议。谢谢。

2013-08-09 - 解决方案

我在下面发布了我的最终工作解决方案。

最佳答案

找到解决方案。

String modulusString = "hm2oRCtP6usJKYpq7o1K20uUuL11j5xRrbV4FCQhn/JeXLT21laKK9901P69YUS3bLo64x8G1PkCfRtjbbZCIaa1Ci/BCQX8nF2kZVfrPyzcmeAkq4wsDthuZ+jPInknzUI3TQPAzdj6gim97E731i6WP0MHFqW6ODeQ6Dsp8pc=";
String publicExponentString = "AQAB";

byte[] modulusBytes = Base64.decodeBase64(modulusString);
byte[] exponentBytes = Base64.decodeBase64(publicExponentString);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger publicExponent = new BigInteger(1, exponentBytes);

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

byte[] plainBytes = clearTextPassword.getBytes("UTF-16LE");
byte[] cipherData = cipher.doFinal(plainBytes);
String encryptedStringBase64 = Base64.encodeBase64String(cipherData);

关于c# - 将 C# RSACryptoServiceProvider 转换为 JAVA 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20655419/

相关文章:

c# - 指定为可选 Func<> 的扩展方法

java - 在小程序中显示图像并播放音频片段

c - 统一认证库

Linux - 保护环境变量

c# - 将资源中的图像添加到 XAML

c# - GroupBox 控件中的选项卡索引

c# - 如何反编译c++ dll?

在本地机器上使用 Eclipse 和远程调试的 Java 热交换

java - 在 Spring 表单中显示 ArrayList

c# - WCF 查询拦截器 : Is this MSDN sample a security risk?