c# RSA 使用私钥加密
c# RSA encrypt with private key
使用public密钥加密并使用私钥解密时加密和解密成功:
使用public密钥的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 使用 public 密钥解密时发生错误填充错误:
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 密钥解密(失败)
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));
}
我明白 public 密钥应该用于加密 decryption.But 在我的情况下,我需要将 public 密钥发送给多个客户端以对文本进行解密由其私钥加密。除客户外,其他人应该无法阅读文本。
任何人都可以看到我的代码有什么问题,或者对我的问题提出更好的解决方案。
使用 public 密钥的私有 key/decrypting 加密是 RSA 中的合法操作,然而 不是 用于保护数据,而是用于验证数据的来源及其完整性。在这种情况下,加密操作通常称为 "signing".
如您所述,使用私钥加密来保护数据是不安全的,因此不容易做到这一点很可能是有意为之,旨在防止算法的不正确使用。
按照评论中的建议将您的私钥分发给客户也是不明智的,因为您无法控制他们将密钥传递给谁(意外或其他原因)。
如果您希望加密数据以便它可以被多个不同的方解密,那么您应该让他们每个人为您提供他们自己的 public 密钥,并使用它分别加密数据每个客户。
RSA 加密只有在使用(安全的)填充方案时才是安全的。 RSA 加密方案已由 RSA 实验室(现在是 EMC2 的一部分)在 PKCS#1 标准中指定。这些已被复制到 RFC 中,例如 RFC 3447: Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1.
For the purposes of this document, an encryption scheme consists of
an encryption operation and a decryption operation, where the
encryption operation produces a ciphertext from a message with a
recipient's RSA public key, and the decryption operation recovers the
message from the ciphertext with the recipient's corresponding RSA
private key.
所以用私钥加密是一个未定义的操作。
那么现在要做什么:
- 安全地 分发私钥而不是 public 密钥
- 生成密钥对并安全地将public密钥传输给发送者
- 如果您需要 authentication/integrity 而不是机密性,请使用签名生成而不是加密
而且,无论您做什么,请阅读 Public 密钥基础设施 (PKI)。这是一个非常复杂的主题,您需要在应用它之前先了解它。
使用public密钥加密并使用私钥解密时加密和解密成功:
使用public密钥的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 使用 public 密钥解密时发生错误填充错误:
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 密钥解密(失败)
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));
}
我明白 public 密钥应该用于加密 decryption.But 在我的情况下,我需要将 public 密钥发送给多个客户端以对文本进行解密由其私钥加密。除客户外,其他人应该无法阅读文本。 任何人都可以看到我的代码有什么问题,或者对我的问题提出更好的解决方案。
使用 public 密钥的私有 key/decrypting 加密是 RSA 中的合法操作,然而 不是 用于保护数据,而是用于验证数据的来源及其完整性。在这种情况下,加密操作通常称为 "signing".
如您所述,使用私钥加密来保护数据是不安全的,因此不容易做到这一点很可能是有意为之,旨在防止算法的不正确使用。
按照评论中的建议将您的私钥分发给客户也是不明智的,因为您无法控制他们将密钥传递给谁(意外或其他原因)。
如果您希望加密数据以便它可以被多个不同的方解密,那么您应该让他们每个人为您提供他们自己的 public 密钥,并使用它分别加密数据每个客户。
RSA 加密只有在使用(安全的)填充方案时才是安全的。 RSA 加密方案已由 RSA 实验室(现在是 EMC2 的一部分)在 PKCS#1 标准中指定。这些已被复制到 RFC 中,例如 RFC 3447: Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1.
For the purposes of this document, an encryption scheme consists of an encryption operation and a decryption operation, where the encryption operation produces a ciphertext from a message with a recipient's RSA public key, and the decryption operation recovers the message from the ciphertext with the recipient's corresponding RSA private key.
所以用私钥加密是一个未定义的操作。
那么现在要做什么:
- 安全地 分发私钥而不是 public 密钥
- 生成密钥对并安全地将public密钥传输给发送者
- 如果您需要 authentication/integrity 而不是机密性,请使用签名生成而不是加密
而且,无论您做什么,请阅读 Public 密钥基础设施 (PKI)。这是一个非常复杂的主题,您需要在应用它之前先了解它。