【发布时间】:2015-12-25 07:19:52
【问题描述】:
用公钥加密和用私钥解密时加密和解密成功:
使用公钥进行 C# 加密(成功)
public string EncryptData(string data) {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xml); //public key
var cipher = rsa.Encrypt(Encoding.UTF8.GetBytes(data), false);
return Convert.ToBase64String(cipher );
}
用私钥进行Java解密(成功)
public static void decrypt() throws Exception{
byte[] modulusBytes = Base64.getDecoder().decode(mod);
byte[] dByte = Base64.getDecoder().decode(d);
BigInteger modulus = new BigInteger(1, (modulusBytes));
BigInteger exponent = new BigInteger(1, (dByte));
RSAPrivateKeySpec rsaPrivKey = new RSAPrivateKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privKey = fact.generatePrivate(rsaPrivKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] cipherData = Base64.getDecoder().decode(cipherByte);
byte[] plainBytes = cipher.doFinal(cipherData);
System.out.println(new String(plainBytes));
}
问题来了
当c#用私钥加密,java用公钥解密时出现bad padding错误:
使用私钥进行 C# 加密(失败)
public stringEncryptData(string data) {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xml); //private key
var cypher = rsa.Encrypt(Encoding.UTF8.GetBytes(data), false);
return Convert.ToBase64String(cypher);
}
用公钥解密java(失败)
public static void decryptPublic() throws Exception{
byte[] modulusBytes = Base64.getDecoder().decode(mod);
byte[] expBytes = Base64.getDecoder().decode(exp);
BigInteger modulus = new BigInteger(1, (modulusBytes));
BigInteger exponent = new BigInteger(1, (expBytes));
RSAPublicKeySpec pubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey publicKey = fact.generatePublic(pubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, publicKey );
byte[] cipherData = Base64.getDecoder().decode(cipherByte);
byte[] plainBytes = cipher.doFinal(cipherData);
System.out.println(new String(plainBytes));
}
我知道公钥应该用于加密,私钥用于解密。但在我的情况下,我需要将公钥发送给多个客户端,以便对其私钥加密的文本进行解密。除客户端外,其他人不应阅读文本。 谁能看到我的代码有什么问题,或者为我的问题提出更好的解决方案。
【问题讨论】:
-
用公钥加密,用私钥解密。将私钥副本提供给需要解密副本的每个人,但不要尝试反转算法。
-
@WDS 正如我的回答中所述,分发私钥也是一个非常糟糕的主意,因为您完全无法控制其他各方可能与谁共享密钥,并且大大增加了处理泄露的密钥。
-
@CY LIM:你的加密和解密方法应该是镜像的,这意味着如果你在你的 JAVA 解密函数中使用 PKCS1 填充(
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")),你也应该在你的 C# 加密函数中使用 PKCS1 填充var cypher = rsa.Encrypt(Encoding.UTF8.GetBytes(data), false);和var cypher = rsa.Encrypt(Encoding.UTF8.GetBytes(data), RSAEncryptionPadding.Pkcs1);。 msdn.microsoft.com/en-us/library/mt132684%28v=vs.110%29.aspx -
“向多个客户端发送公钥” 是错误的。在服务器端,您需要使用 client public key encrypt 并使用 server private key sign。客户端将使用服务器公钥验证签名,并使用自己的私钥解密。
标签: java c# encryption cryptography rsa