使用.NET进行公钥加密,使用Java进行解密
本文关键字:使用 解密 Java 公钥加密 NET | 更新日期: 2023-09-27 18:27:28
我有一个要求,Java Web服务公开客户端获取PublickKey(作为PEM字符串)的方法,并向使用PublicKey加密的Web服务提交数据。该服务的客户端是.NET应用程序。在Java端,使用密钥对(RSA 1024位)创建密钥库,如下所示keytool.exe-genkey-alias abc-keystore sample.ks-storetype jceks-storepass xyz
.NET客户端通过web服务获得PublicKey,然后使用该公钥加密一些敏感数据,以使用加密的数据调用web服务。web服务使用密钥库中可用的私钥解密数据,并将内容存储在DB中。由于客户端兼容性的原因,我无法使用任何WS-Security功能。
Web服务读取密钥库,并将公钥作为PEM字符串返回。.NET客户端获取作为PEM字符串的PublicKey,并使用它创建RSACryptoServiceProvider,它可以毫无问题地工作。然后它解密数据并将其提交回Java Web服务。
Java服务解密数据,但我遇到的问题是它打印出垃圾(而不是ASCII数据)。我没有得到任何异常
我在这里附上了代码的片段(简化)
.NET客户端
var registrationService = new RegistrationService();
var pKey = registrationService.getPublickey();
//pKey is a PEM String
X509Certificate2 cert = new X509Certificate2(ASCIIEncoding.ASCII.GetBytes(pKey));
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
var encryptedMsg = rsa.Encrypt(Encoding.UTF8.GetBytes("Secret Data"), false);
var encoded_msg = Convert.ToBase64String(encryptedMsg);
registrationService.submitRegistration(encoded_msg);
Java端:
public void submitRegistration(String inputData)
{
//Decoding the encoded and encrypted message in the webservice
PrivateKey privateKey = getPrivateKeyFromKeyStore("abc");
//I know I am using JDK proprietary classes, but I can easily replace this
byte[] dataInBytes = new Base64Decoder().deodeBuffer(inputData)
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(dataInBytes);
String original = new String(decryptedData, "UTF-8");
System.out.println("Original Data : " + original);
}
public String getPublicKey()
{
Certificate cert = getKeyStore().getCertificate("abc");
byte[] encodedCert = cert.getEncoded();
StringWriter sw = new StringWriter();
sw.write("-----BEGIN PUBLIC KEY-----");
sw.write(new Base64Encoder().encode(encodedCert));
sw.write("-----END PUBLIC KEY-----");
return sw.toString();
}
需要注意的一点是,您在Java端使用"NOPADDING",但.NET使用的是PKCS1Padding。
由于PKCS1填充在高位端用0x00 0x02填充明文,这也为解密端提供了一种检查其是否使用正确私钥的方法。但是,请注意,错误的密钥解密为以0x00 0x02开头的明文的几率至少为1/65536,因此不能完全依靠此检查来检测不正确的私钥。在您的情况下,您使用了不正确的密钥,并且明文未通过此检查,因此您收到了异常。现在,当您指定NOPADDING时,您表示所有明文都是有效的,任何进一步的检查都将由您的应用程序完成。