我有一个要求,即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功能。
webservice读取密钥库并将公钥作为PEM字符串返回。 .NET客户端将PublicKey作为PEM字符串获取并使用它创建一个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 Side:
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();
}
答案 0 :(得分:2)
有一点需要注意的是,你在Java端使用“NOPADDING”,但.NET正在使用PKCS1Padding。
由于PKCS1填充垫在高位端具有0x00 0x02的明文,这也为解密端提供了一种检查它是否使用正确的私钥的方法。但请注意,错误密钥解密为以0x00 0x02开头的明文的可能性至少为1/65536,因此不能完全依赖此检查来检测不正确的私钥。在您的情况下,您使用了错误的密钥,并且明文未通过此检查,因此您收到了异常。现在,当您指定NOPADDING时,您说所有明文都是有效的,并且您的应用程序将进行任何进一步的检查。