我需要将私钥中的加密字符串发送到网络服务器以进行身份验证。我有正确生成加密字符串的 Java 客户端代码(以便网络服务器可以使用公钥对其进行解密)。我正在尝试编写 C# 代码来执行完全相同的加密 - 但没有成功。
首先在 java 中使用类似这样的 keytool 生成了一个 keystore :
keytool -genkey -dname "cn=Application Test, ou=XXX, o=YYY, c=US" -alias AppTest -keypass AppTest -keystore AppTest.jks -storepass AppTest -validity 1800 -keyalg RSA
然后此 java 代码正确读取 keystore 并加密数据(privateKey.getAlgorithm() 返回“RSA”):
KeyStore ks = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream("AppTest.jks");
ks.load(is, "AppTest".toCharArray());
is.close();
PrivateKey privateKey = (PrivateKey) ks.getKey(user, password.toCharArray());
// Encrypt with the private key
String stamp = "123456";
byte[] bytesStampUtf8Unencrypted = stamp.getBytes(Charset.forName("UTF-8"));
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytesTimestampUtf8Encrypted = cipher.doFinal(bytesStampUtf8Unencrypted);
String encrypted = new String((new Base64()).encode(bytesStampUtf8Unencrypted));
当传递给网络服务时,这一切都很好用。然后,我使用 keytool 将 java keystore 转换为 PKCS12 证书,以便在我的 .NET 应用程序中使用:
keytool -importkeystore -srckeystore AppTest.keystore -destkeystore KEYSTORE.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass AppTest -deststorepass AppTest-srcalias AppTest -destalias AppTest -srckeypass AppTest -destkeypass AppTest -noprompt
我使用 keytool 比较了 keystore 和 P12 文件的指纹 - 相同。我认为以下 C# 代码应该可以工作:
X509Certificate2 myCertificate =
new X509Certificate2(@"C:\Temp\KEYSTORE.p12", "AppTest");
RSACryptoServiceProvider privateKey =
myCertificate.PrivateKey as RSACryptoServiceProvider;
String stamp = "123456";
byte[] buffer = Encoding.UTF8.GetBytes(stamp);
byte[] encryptedBytes = privateKey.Encrypt(buffer, false);
String encrypted = Convert.ToBase64String(encryptedBytes);
它正确读取转换后的 keystore 文件,没有问题地执行,并生成看似加密的数据,但 Web 服务不喜欢加密的字符串(无法使用公钥解密)。当我将 C# 加密字符串替换为 Java 加密字符串(在调试器中)并通过 C# 程序将该字符串发送到 Web 服务时——一切正常——所以我相信问题出在加密过程中,而不是在网络服务通信中。
我无法控制原始 key 的生成方式(作为 Java keystore ),也无法控制 Web 服务期望的加密方法。我只能控制与基于 Java 的 Web 服务交互的 .NET 客户端。
我是否遗漏了一些标志、设置、变量等等?
最佳答案
与您的 java 相比,您确定加密算法、分组密码模式 和填充模式 在您的 C# 实现中是等效的吗实现?
编辑:实际上,对于 RSACryptoProvider,您可能不需要密码/填充模式 - 查看 MSDN 上的示例,特别是关于通过 ImportParameters 导入公钥信息的部分
关于c# - 如何在 C# .NET 中像 Java 代码一样加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2383322/