【问题标题】:Why RSA encryption can return different results with C# and Java?为什么 RSA 加密可以使用 C# 和 Java 返回不同的结果?
【发布时间】:2010-04-02 18:14:05
【问题描述】:

我使用:

  • c#: RSACryptoServiceProvider
  • JAVA:KeyFactory.getInstance("RSA")+Cipher

我将公钥(指数 + 模数)作为字节数组从 java 发送到 c#。没关系,有相同的字节。但是当我尝试用 Java 和 c# 中的一个密钥加密一些数据时 - 会有不同的结果。

Java 密钥生成:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize( Config.CRYPTO_KEY_NUM_BITS );

m_KeyPair = keyGen.genKeyPair();

m_PublicKey = KeyFactory.getInstance("RSA").generatePublic(
 newX509EncodedKeySpec(m_KeyPair.getPublic().getEncoded()));

byte[] exponent = m_PublicKey.getPublicExponent().toByteArray();
byte[] modulus  = m_PublicKey.getModulus().toByteArray(); // then sending...

C# 密钥接收:

// Recieved...
m_ExternKey = new RSAParameters();
m_ExternKey.Exponent    = exponent;
m_ExternKey.Modulus     = modulus;

m_RsaExtern = new RSACryptoServiceProvider();
m_RsaExtern.ImportParameters(m_ExternKey);

byte[] test = m_RsaExtern.Encrypt(bytesToEncrypt, true);

问题是加密字节不同。

谢谢。

【问题讨论】:

    标签: c# java rsa


    【解决方案1】:

    RSA 加密是随机的。对于给定的公钥和给定的消息,每次加密尝试都会产生不同的字节序列。这是正常的,也是意料之中的;随机字节是作为填充阶段的一部分注入的,不注入随机字节会导致加密系统较弱。在解密过程中,填充字节被定位并移除,原始消息被完好无损地恢复。

    因此,如果您两次运行 Java 或 C# 代码,预计您将收到不同的加密消息。

    【讨论】:

    • +1 我没有尝试过,但我也很确定随机填充会导致这种情况。
    【解决方案2】:

    RSA Encription 不能使用模拟密钥返回不同的值 - 它的标准化算法。检查你的钥匙。

    【讨论】:

    • 通常在 RSA 加密之前添加随机数据填充(参见 pkcs #1,OAEP)。
    【解决方案3】:

    如果我没记错的话,RSA 参数包含比模数和指数更多的参数。您需要完全初始化 rsa 参数才能正确加密(在 .net 中)。

    此外,您的私钥和私钥甚至没有在.net中设置

    【讨论】:

    • 是的,但据我所知,RSA 只需要公共指数和模数来加密。其他参数用于解密。
    • 理论上可以,但可能是实现需要更多。我会尝试使用包含私钥的证书并使用该证书进行加密。
    【解决方案4】:

    我希望这对 C# lough 代码有帮助

                byte[] rsaExp = rsaParameters.Exponent.ToByteArray();
                byte[] Modulus = rsaParameters.Modulus.ToByteArray();
    
                // Microsoft RSAParameters modulo wants leading zero's removed so create new array with leading zero's removed
                int Pos = 0;
                for (int i = 0; i < Modulus.Length; i++)
                {
                    if (Modulus[i] == 0)
                    {
                        Pos++;
                    }
                    else
                    {
                        break;
                    }
                }
                byte[] rsaMod = new byte[Modulus.Length - Pos];
                Array.Copy(Modulus, Pos, rsaMod, 0, Modulus.Length - Pos);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-03
      • 2010-10-31
      相关资源
      最近更新 更多