c# - 如何用 c sharp 解密 "encrypted string with java"?

标签 c# java android encryption rsa

我有一个字符串。用java加密的。现在我必须用 c sharp 来解密它。

我在 c sharp 和 java 中使用具有相同公钥/私钥的 RSA 算法。

但是在用 c sharp 解密时我得到了一个“Bad Data”错误。

还有一个重要的通知是:我可以用java解密这个字符串!我可以用 c sharp 加密,用 c sharp 解密!!但是当我尝试用其中一个(c sharp 或 java)加密并用另一个解密时,它会引发错误!

这是我的 c sharp 代码:

string privateKey = "<RSAKeyValue><Modulus>rFsMn+idg8jmVMk249DzJc7AFft3+/jcnYDTh9wHee3tgFu1gBRh7e+ao+MWq7NEN0N7kUHa7O4c/ND2Ahcx/h4mXD5KDoixFRBUsxYqCJVA68qYJ7vozVPMjNr4jeOo1xt+oevO5+mUWtcaib5Iw51u1Jq/6qCqLsm8Eq3cnsE=</Modulus><Exponent>AQAB</Exponent><P>5aqTyz3GH655H+vO/BzJvFzpILpxLwXZEvqp3l3NYXKqP0tdkY1g36o6M9YodI3h8ho4VFYofIqA1+V0qPkuDQ==</P><Q>wB45uljBS8Z+WGRE1cRdpZb5aKUv76uLlCp6agtPBBhjXNIQrN8MpOCTvZM2cOsuYpYhDtnwsTY9KKXdBmv6hQ==</Q><DP>KB474uzPhwk7L1BJv9BnjPfN4WGwE765xI70zVslXThidNv9ZEeF/IwHzrZCKtn99gSOgmzqdZbcGtqCHmIooQ==</DP><DQ>eLnFrvsdJJ/sP2Fq/CX0bx0rR34eXG6hPI9g84h9s+YbcnWy8t8LVASn8oYyvMydDminB20e2k1qK0PnW6S4/Q==</DQ><InverseQ>rlPpLse8LJ0KRglnu2D1xzJT90QqzS3o80P0WTpUvm95mF5d8YaVj/d9W7FBdgZ98y6Q7of+wLCmYGKLg56wYQ==</InverseQ><D>Gs8mzZDPP3p2aWXLBfCwgYcBVeoBpc318wHg5VcSSqL5uGeLedqxyOLmOOvP0PFXgQkcJWIK/aOkGqcePQECo3TNiK+uLSwc97V3spZah70FFJVyh23Y+o0wlRGHAm5Nj9QieHlVwhgJPkNUJYgH9qkwB9aCpl+rdAG3da2fQ2E=</D></RSAKeyValue>";
string publicKey = "<RSAKeyValue><Modulus>rFsMn+idg8jmVMk249DzJc7AFft3+/jcnYDTh9wHee3tgFu1gBRh7e+ao+MWq7NEN0N7kUHa7O4c/ND2Ahcx/h4mXD5KDoixFRBUsxYqCJVA68qYJ7vozVPMjNr4jeOo1xt+oevO5+mUWtcaib5Iw51u1Jq/6qCqLsm8Eq3cnsE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";



public string EncryptData(string data2Encrypt )
{
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(publicKey);
    byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data2Encrypt);
    byte[] cipherbytes = rsa.Encrypt(plainbytes, false);
    return Convert.ToBase64String(cipherbytes);
}

public string DecryptData(string data2Decrypt)
{
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(privateKey);
    byte[] plainbytes = rsa.Decrypt(Convert.FromBase64String(data2Decrypt), false);
    return System.Text.Encoding.UTF8.GetString(plainbytes);
}

我的java代码是:

byte[] expBytes = Base64.decode("AQAB".getBytes("UTF-8"), Base64.DEFAULT);
byte[] modBytes = Base64.decode("rFsMn+idg8jmVMk249DzJc7AFft3+/jcnYDTh9wHee3tgFu1gBRh7e+ao+MWq7NEN0N7kUHa7O4c/ND2Ahcx/h4mXD5KDoixFRBUsxYqCJVA68qYJ7vozVPMjNr4jeOo1xt+oevO5+mUWtcaib5Iw51u1Jq/6qCqLsm8Eq3cnsE=".getBytes("UTF-8"), Base64.DEFAULT);
byte[] dBytes = Base64.decode("Gs8mzZDPP3p2aWXLBfCwgYcBVeoBpc318wHg5VcSSqL5uGeLedqxyOLmOOvP0PFXgQkcJWIK/aOkGqcePQECo3TNiK+uLSwc97V3spZah70FFJVyh23Y+o0wlRGHAm5Nj9QieHlVwhgJPkNUJYgH9qkwB9aCpl+rdAG3da2fQ2E=".getBytes("UTF-8"), Base64.DEFAULT);

BigInteger modules = new BigInteger(1, modBytes);
BigInteger exponent = new BigInteger(1, expBytes);
BigInteger d = new BigInteger(1, dBytes);

KeyFactory factory = KeyFactory.getInstance("RSA");
Cipher cipher = Cipher.getInstance("RSA");
String input = "test";

RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modules, exponent);
PublicKey pubKey = factory.generatePublic(pubSpec);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cipher.doFinal(input.getBytes());

String strEncrypted = Base64.encodeToString(encrypted, Base64.DEFAULT);

我无法解码 c sharp 中的 strEncrypted 值。

最后,java 中的加密值与 c sharp 不同(相同的 key 、算法和数据)!!!

最佳答案

RSACryptoServiceProvider.Encrypt(plainbytes, false) 的第二个参数表示使用 PKCS#1 填充。 true 用于 OAEP 填充。

在 Java 中,您使用的安全提供程序将 "RSA" 映射到 "RSA/ECB/NoPadding",这只是没有任何填充的加密,因此加密结果是总是一样。因此需要指定 "RSA/ECB/PKCS1Padding" 以匹配 C# 行为。

您应该始终指定模式和填充,否则安全提供商将选择它自己的默认值 - 每个提供商的默认值可能不同。

关于c# - 如何用 c sharp 解密 "encrypted string with java"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22742097/

相关文章:

java - Java 编辑器中的 Eclipse SVN 更改历史记录

java - 如何使用 HTTPClient 设置 HTTP 请求 header "authentication"?

java - 如何将数据附加到现有 Dropbox 文件?

c# - IList<T>.FindIndex(Int32, Predicate <T>)

javascript - ASP .NET MVC 无法使用 jQuery/JavaScript 提交表单

c# - 是否有基于 TPL(异步/等待)的套接字抽象?

java - 安卓服务类路径

Android 自动与自定义数据同步

android - 当客户端是 Android 时如何在不使用 SSL 的情况下保护 GAE 数据库

c# - 具有强类型索引的多维数组的最佳混合方法