C# 使用Bouncy Castle解决C和Java之间的RSA加密问题
我在一个Java应用程序和另一个C语言应用程序中遇到了几个问题。有一个服务器应用程序,它通过HTTP接收请求,处理并发送 支持回答。该服务器使用Bouncy Castle用Java编写,我们使用PKI加密请求中的敏感数据。我们有许多服务器可以识别的操作 其中一个用于生成用于和客户端交换的公钥和私钥。每个客户端都有一个唯一的ID,因此当此操作命名为 执行GetEncryptionKey时,它会生成私钥并将其保存在服务器本地,并生成以PEM格式发回的公钥,如下所示:C# 使用Bouncy Castle解决C和Java之间的RSA加密问题,c#,java,encryption,bouncycastle,C#,Java,Encryption,Bouncycastle,我在一个Java应用程序和另一个C语言应用程序中遇到了几个问题。有一个服务器应用程序,它通过HTTP接收请求,处理并发送 支持回答。该服务器使用Bouncy Castle用Java编写,我们使用PKI加密请求中的敏感数据。我们有许多服务器可以识别的操作 其中一个用于生成用于和客户端交换的公钥和私钥。每个客户端都有一个唯一的ID,因此当此操作命名为 执行GetEncryptionKey时,它会生成私钥并将其保存在服务器本地,并生成以PEM格式发回的公钥,如下所示: encryptionKey=--
encryptionKey=-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAon1WDHdarN7yq0UOevzW
5PiFsSC8bEkTUOZ6X3RIth+RCU42pUj/Z8fp9T8rbWp8CqbhlFDxU4c+YucpGljC
7A10nkrPoBT0lpHEuXJiSgx+9qqsyo9q6GddhOpdMa+Z6VCfI+JCM3kdJNMH3r+o
i+WLPHLB8lxnfT2CHyZVQGhkzrH9fk1XhdenXxjtPGpwYBOsUZUwRt8EeW6JUwSI
mKXiXag0IViEcyAa2BvProkxklbQB3BczLHdXjIDwnE6u1aMA7pYPSkBtY6tuQ0F
5sNWXHsaKWON33MnbhlM7sieYDi9L4dWksala/m/mdIeHIXzX4ZCYdOhayWWKZ1N
HwIDAQAB
-----END PUBLIC KEY-----
这工作正常。用于生成密钥的代码如下所示:
private void getEncryptedKey() throws GWTranException {
PEMWriter pemWriter;
Security.addProvider(new BouncyCastleProvider());
KeyPair keyPair = null;
KeyPairGenerator keyPairGenerator = null;
try {
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
StringWriter writer = new StringWriter();
try {
pemWriter = new PEMWriter(new PrintWriter(writer));
pemWriter.writeObject(keyPair.getPublic());
pemWriter.flush();
String pem = writer.toString();
savePrivateKey(keyPair, pem); // save the private key locally
} catch (IOException e) {
e.printStackTrace();
}
}
现在我有了一个用C编写的客户端,它连接到服务器,检索响应中发送的公钥,并使用它加密将加密的字符串。
这是非常简单的.NET代码,因为我只是在测试功能:
private string EncryptDataWithRSA(string data) {
string cryptedData = string.Empty;
RsaKeyParameters rsaParams;
using (var reader = new StringReader(txtKey.Text)) {
rsaParams = (RsaKeyParameters)new PemReader(reader).ReadObject();
reader.Close();
}
IAsymmetricBlockCipher eng = new RsaEngine();
eng = new OaepEncoding(eng);
eng.Init(true, rsaParams);
var dataBytes = Encoding.UTF8.GetBytes(data);
var cryptedDataBytes = eng.ProcessBlock(dataBytes, 0, dataBytes.Length);
cryptedData = Convert.ToBase64String(cryptedDataBytes);
return cryptedData;
}
一切看起来都不错,但问题是,当服务器Java应用程序尝试解密数据时,我遇到了一个异常:
javax.crypto.BadPaddingException: data hash wrong
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.verifone.gateway.security.RSAEncryptUtil.decrypt(RSAEncryptUtil.java:127)
at com.verifone.gateway.security.RSAEncryptUtil.decrypt(RSAEncryptUtil.java:152)
at com.verifone.gateway.preonline.PreOnlineJob.decryptData(PreOnlineJob.java:1661)
at com.verifone.gateway.preonline.PreOnlineJob.extractCardData(PreOnlineJob.java:989)
at com.verifone.gateway.preonline.PreOnlineJob.run(PreOnlineJob.java:288)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
这与另一个客户端在iOS中写的情况很好,但我没有访问源代码的权限。我正在用.NET写一个模拟器,但我不能
正确解密信息。在服务器端,这是用于解密数据的代码的一部分:
public static byte[] decrypt(byte[] text, PrivateKey key) throws Exception
{
byte[] dectyptedText = null;
try {
// decrypt the text using the private key
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
}
catch (Exception e) {
//_log.error(e, e);
throw e;
}
return dectyptedText;
}
我没有主意了,我什么都试过了。你看到我没有看到的东西了吗?
感谢您的帮助。删除起始“encryptionKey=”中的文本这可能是个问题。此外,如果您在代码中的任何地方编辑了密钥,请不要这样做。即使删除一个空链接也不是万能的。不,这部分不是用来获取密钥的。已正确创建RsaKeyParameters对象。我不会改变钥匙上的任何东西。谢谢ZeusI看到你在客户端上转换为base64,是从base64解码为byte[]吗?很好。无论如何,是的,它将它从Base64转换为:BASE64Decoder b64=新的BASE64Decoder;返回b64.decodeBuffertext;