C# .net到CryptoServiceProvider不工作

C# .net到CryptoServiceProvider不工作,c#,encryption,mono,C#,Encryption,Mono,我目前正在将我的一个库移植到mono,以使其可用于MonoMac。 我在这个库中使用RSA,但它的工作方式不一样:它在.NETFramework4中工作得很好,但在mono中它不再工作了 我正在使用RSA交换密钥,以下是服务器端代码: private void SecureConnection() { RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSAParameters RSAKeyInfo =

我目前正在将我的一个库移植到mono,以使其可用于MonoMac。 我在这个库中使用RSA,但它的工作方式不一样:它在.NETFramework4中工作得很好,但在mono中它不再工作了

我正在使用RSA交换密钥,以下是服务器端代码:

private void SecureConnection()
{
    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
    RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
    NetStream.Write(RSAKeyInfo.Modulus, 0, RSAKeyInfo.Modulus.Length);
    NetStream.Flush ();
    byte[] keyReceived = new byte[128];
    byte[] IvReceived = new byte[128];
    int position = 0;
    while (position < 127) {
        position += NetStream.Read (keyReceived, position, 128 - position);
    }
    position = 0;
    while (position < 127) {
        position += NetStream.Read (IvReceived, position, 128 - position);
    }
    byte[] realKey = RSA.Decrypt(keyReceived, true);
    byte[] realIv = RSA.Decrypt(IvReceived, true);
    Rijndael = new RijndaelManaged { Key = realKey, IV = realIv };
    Encrypt = Rijndael.CreateEncryptor();
    Decrypt = Rijndael.CreateDecryptor();
    FullName = WaitAndGetString();
    Debug.WriteLine("[TCP] TcpHandler -> Connection to {0} ({1}) secured successfully", TcpClient.RemoteEndPoint, FullName);
}
private void SecureConnection()
{
RSACryptoServiceProvider RSA=新的RSACryptoServiceProvider();
rsacameters RSAKeyInfo=RSA.ExportParameters(false);
Write(RSAKeyInfo.module,0,RSAKeyInfo.module.Length);
Flush();
字节[]keyReceived=新字节[128];
字节[]IvReceived=新字节[128];
int位置=0;
而(位置<127){
position+=NetStream.Read(keyReceived,position,128-position);
}
位置=0;
而(位置<127){
position+=NetStream.Read(IvReceived,position,128-position);
}
字节[]realKey=RSA.Decrypt(keyReceived,true);
字节[]realIv=RSA.Decrypt(IvReceived,true);
Rijndael=新的RijndaelManaged{Key=realKey,IV=realIv};
Encrypt=Rijndael.CreateEncryptor();
Decrypt=Rijndael.CreateDecryptor();
FullName=WaitAndGetString();
Debug.WriteLine(“[TCP]TcpHandler->到{0}({1})的连接已成功保护”,TcpClient.RemoteEndPoint,全名);
}
下面是客户端实现:

private ConnectedClient SecureConnection(TcpClient toSecure)
{
     NetworkStream netStr = toSecure.GetStream();
     ConnectedClient cc = new ConnectedClient
     {
        TcpClient = toSecure,
        NetStream = netStr
     };
     byte[] buffer = new byte[128];
     int position = 0;
     while (position < 127) 
     {
         position += netStr.Read (buffer, position, 128 - position);
     }
     RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
     RSAParameters RSAKeyInfo = new RSAParameters
     {
        Exponent = new byte[] {1, 0, 1}, 
        Modulus = buffer
     };
     RSA.ImportParameters(RSAKeyInfo);
     Rijndael rjindael = new RijndaelManaged();
     rjindael.GenerateKey();
     rjindael.GenerateIV();
     byte[] keyToSend = RSA.Encrypt(rjindael.Key, true);
     byte[] IvToSend = RSA.Encrypt(rjindael.IV, true);
     netStr.Write(keyToSend, 0, 128);
     netStr.Flush();
     netStr.Write(IvToSend, 0, 128);
     netStr.Flush();
     cc.Encrypt = rjindael.CreateEncryptor();
     cc.Decrypt = rjindael.CreateDecryptor();
     cc.Rijndael = rjindael;
     Debug.WriteLine("[TCP] ConnectedClient -> Connection to " + toSecure.Client.RemoteEndPoint + " secured successfully");
     cc.WriteOnStream(SharedGlobals.FullUsername);
     return cc;
}
专用连接客户端安全连接(TcpClient-to-secure)
{
NetworkStream netStr=toSecure.GetStream();
ConnectedClient cc=新的ConnectedClient
{
TcpClient=toSecure,
NetStream=netStr
};
字节[]缓冲区=新字节[128];
int位置=0;
而(位置<127)
{
位置+=netStr.Read(缓冲区,位置,128-位置);
}
RSACryptoServiceProvider RSA=新的RSACryptoServiceProvider();
rsacameters RSAKeyInfo=新的rsacameters
{
指数=新字节[]{1,0,1},
模数=缓冲器
};
RSA.ImportParameters(RSAKeyInfo);
Rijndael rjindael=新的RijndaelManaged();
rjindael.GenerateKey();
rjindael.GenerateIV();
字节[]keyToSend=RSA.Encrypt(rjindael.Key,true);
字节[]IvToSend=RSA.Encrypt(rjindael.IV,true);
netStr.Write(keyToSend,0,128);
netStr.Flush();
netStr.Write(IvToSend,0,128);
netStr.Flush();
cc.Encrypt=rjindael.CreateEncryptor();
cc.Decrypt=rjindael.CreateDecryptor();
cc.Rijndael=rjindael;
Debug.WriteLine(“[TCP]ConnectedClient->连接到”+toSecure.Client.RemoteEndPoint+“已成功保护”);
cc.WriteOnStream(SharedGlobals.FullUsername);
返回cc;
}
问题出在客户端:
byte[]realKey=RSA.Decrypt(keycreceived,true)
正在抛出带有
OAEP解码错误的
加密异常

此异常仅在Mono中引发,而不是在标准.Net中引发


知道为什么吗?

这个问题是因为.Net和Mono之间的指数不一样。Net总是生成一个
字节[]{1,0,1}
(至少从我看到的情况来看)。因此,现在我用公钥发送指数,它工作得很好。

第一个问题:您正在调用
Stream.Read
并完全忽略结果。你怎么知道你已经完全阅读了密钥和IV?我会尝试循环,直到得到合适的大小,然后我会更新我的问题。编辑我的帖子,我仍然有相同的问题。你正在实例化大量的对象,它们的类实现了
IDisposable
接口。您应该使用
语句将他们的生命周期包装在
中。1)您的客户假设e=65537,但我认为
新的RSACryptServiceProvider
的文档不能保证这种情况。我也看不到生成1024位密钥的保证。2) 将字节数组(十六进制编码)转储到程序中多个点的控制台,以便通过检查服务器和客户端上的字节是否相同,可以看到错误是在哪里引入的。