Java 和 C# 中使用 Bouncy Castle 进行 RSA 加密的结果之间的差异
Difference between results with RSA Encryption with Bouncy Castle in Java and C#
我有一个 Java working 示例应用程序(使用 Bouncy Castle),我需要将其移植到 C#(我也在为 C# 使用 Bouncy Castle) .
代码差不多。但是,即使我为两者提供完全相同的模数和指数,结果数组也完全不同,字符串也是如此。
重申:Java 摘录是有效的代码
我哪里错了?提前致谢!
Java:
public static String encodeRSA(String keyModulus, String keyExponent,
String data) {
try {
byte btMod[] = Base64.decode(keyModulus);
byte btExp[] = Base64.decode(keyExponent);
BigInteger modulus = new BigInteger(1, btMod);
BigInteger pubExp = new BigInteger(1, btExp);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, pubExp);
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherData = cipher.doFinal(data.getBytes());
String tmp = new String(Base64.encode(cipherData));
System.out.println(tmp);
return tmp;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "";
}
C#:
private static string EncodeRSA(string modulus, string exponent, string data)
{
//Base64, DotNetUtilities functions and BigInteger type are from Bouncy Castle
byte[] btMod = Base64.Decode(modulus);
byte[] btExp = Base64.Decode(exponent);
BigInteger mod = new BigInteger(1, btMod);
BigInteger exp = new BigInteger(1, btExp);
RsaKeyParameters bcKeySpec = new RsaKeyParameters(false, mod, exp);
RSAParameters keySpec = DotNetUtilities.ToRSAParameters(bcKeySpec);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(keySpec);
byte[] plaintext = Encoding.UTF8.GetBytes(data);
byte[] ciphertext = rsa.Encrypt(plaintext, false);
string cipherresult = Encoding.UTF8.GetString(Base64.Encode(ciphertext));
return cipherresult;
}
模数:
gdBAMJVXCuEGhX0b1hPAggpD7Ayi33JhsARksGkEatQsdox3BG3bTR/vz8M4vZe74EZj0aZrk0rGJGmAEJZ9GlXq6JzIRYBW5zULsBoPDq4spgobECJLsXq8CnZzOrOM+meIXFhoK8Jyob4X9q62HkDwhMMyqsBG0epWMHPIgkU=
指数:
AQAB
输出:
Java output for the entry "1]teste]111111]MTExMTExMTExMTExMTExMQ=="
using the given modulus/exponent
dUCVsGrZIwSyh0ZAxon3wMSPPoQqflpRNtQ5c+TILuOR/5IihABJpZRL6E1TjYs62WXvQUbeFqRYbdAvbjY3YZk+aSviBosdN54+T8+/5agjveeDBi6LXu6r1+KBriq2K1ULg9YC62SrSbRN8VMJ9gkgatF2ux06PyouJOPJPN8=
编辑 - 具有给定条目、模数和指数的 C# 输出
CHyg5J+OMuG9H9S7R24Lg2iXeLN/Rgh7XcyDQJqMNZobH0V1hqe2dxrcE3R+UrVl/aDWJg3aXNtP3+8YFA17fLr9yIbIYv5o2zeRMdHbyrW/z26JGaynsay096KEzJ0uBAACJQ3LZryd5ei7zzo77Bnka2Un7C9TJvldswhldxM=
RSA 加密或任何安全加密方法的输出,向攻击者输出无法区分的随机数据。这是由对称密码的 IV 和 RSA 的 填充方法 执行的。如果不是这种情况,那么攻击者将能够看到不同密文的相似之处;加密 "yes" 两次,将出现相同的密文。因此攻击者可以轻松区分 E(pk, "yes") | E(pk, "yes")
和 E(pk, "yes") | E (pk, "no")
.
所以Java和C#输出的密文都恰好是编码前模数的大小。然而,在用于 RSA 的模幂运算之前,明文首先用安全的随机数据填充。验证密文生成是否正确的方法是使用私钥对密文进行解密。实际上,如果您多次运行 Java 或 C#,您会发现即使在同一个 language/runtime.
中,密文也会不断变化
我有一个 Java working 示例应用程序(使用 Bouncy Castle),我需要将其移植到 C#(我也在为 C# 使用 Bouncy Castle) .
代码差不多。但是,即使我为两者提供完全相同的模数和指数,结果数组也完全不同,字符串也是如此。
重申:Java 摘录是有效的代码
我哪里错了?提前致谢!
Java:
public static String encodeRSA(String keyModulus, String keyExponent,
String data) {
try {
byte btMod[] = Base64.decode(keyModulus);
byte btExp[] = Base64.decode(keyExponent);
BigInteger modulus = new BigInteger(1, btMod);
BigInteger pubExp = new BigInteger(1, btExp);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, pubExp);
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherData = cipher.doFinal(data.getBytes());
String tmp = new String(Base64.encode(cipherData));
System.out.println(tmp);
return tmp;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "";
}
C#:
private static string EncodeRSA(string modulus, string exponent, string data)
{
//Base64, DotNetUtilities functions and BigInteger type are from Bouncy Castle
byte[] btMod = Base64.Decode(modulus);
byte[] btExp = Base64.Decode(exponent);
BigInteger mod = new BigInteger(1, btMod);
BigInteger exp = new BigInteger(1, btExp);
RsaKeyParameters bcKeySpec = new RsaKeyParameters(false, mod, exp);
RSAParameters keySpec = DotNetUtilities.ToRSAParameters(bcKeySpec);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(keySpec);
byte[] plaintext = Encoding.UTF8.GetBytes(data);
byte[] ciphertext = rsa.Encrypt(plaintext, false);
string cipherresult = Encoding.UTF8.GetString(Base64.Encode(ciphertext));
return cipherresult;
}
模数:
gdBAMJVXCuEGhX0b1hPAggpD7Ayi33JhsARksGkEatQsdox3BG3bTR/vz8M4vZe74EZj0aZrk0rGJGmAEJZ9GlXq6JzIRYBW5zULsBoPDq4spgobECJLsXq8CnZzOrOM+meIXFhoK8Jyob4X9q62HkDwhMMyqsBG0epWMHPIgkU=
指数:
AQAB
输出:
Java output for the entry "1]teste]111111]MTExMTExMTExMTExMTExMQ=="
using the given modulus/exponent
dUCVsGrZIwSyh0ZAxon3wMSPPoQqflpRNtQ5c+TILuOR/5IihABJpZRL6E1TjYs62WXvQUbeFqRYbdAvbjY3YZk+aSviBosdN54+T8+/5agjveeDBi6LXu6r1+KBriq2K1ULg9YC62SrSbRN8VMJ9gkgatF2ux06PyouJOPJPN8=
编辑 - 具有给定条目、模数和指数的 C# 输出
CHyg5J+OMuG9H9S7R24Lg2iXeLN/Rgh7XcyDQJqMNZobH0V1hqe2dxrcE3R+UrVl/aDWJg3aXNtP3+8YFA17fLr9yIbIYv5o2zeRMdHbyrW/z26JGaynsay096KEzJ0uBAACJQ3LZryd5ei7zzo77Bnka2Un7C9TJvldswhldxM=
RSA 加密或任何安全加密方法的输出,向攻击者输出无法区分的随机数据。这是由对称密码的 IV 和 RSA 的 填充方法 执行的。如果不是这种情况,那么攻击者将能够看到不同密文的相似之处;加密 "yes" 两次,将出现相同的密文。因此攻击者可以轻松区分 E(pk, "yes") | E(pk, "yes")
和 E(pk, "yes") | E (pk, "no")
.
所以Java和C#输出的密文都恰好是编码前模数的大小。然而,在用于 RSA 的模幂运算之前,明文首先用安全的随机数据填充。验证密文生成是否正确的方法是使用私钥对密文进行解密。实际上,如果您多次运行 Java 或 C#,您会发现即使在同一个 language/runtime.
中,密文也会不断变化