RSACipher cycles infinitely in while statement of Transform method.

Aug 25, 2011 at 11:02 AM

Hi Oleg,

I'm trying to connect to Windows server with OpenSSH running using RSA key. The authentication works good with other utilities and libraries, but your library hangs. When debugging it occurs that it can't leave the cycle in Transform method of RSACipher class:

        public override BigInteger Transform(BigInteger input)
        {
            var privateKey = this._key as RSAPrivateKey;

            if (privateKey != null)
            {
                BigInteger random = BigInteger.One;

                var max = this._key.Modulus - 1;

                while (random <= BigInteger.One || random >= max)
                {
                    var bytesArray = new byte[256];
                    _randomizer.GetBytes(bytesArray);

                    bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F);   //  Ensure not a negative value
                    random = new BigInteger(bytesArray.Reverse().ToArray());
                }

                BigInteger blindedInput = BigInteger.PositiveMod((BigInteger.ModPow(random, this._key.Exponent, this._key.Modulus) * input), this._key.Modulus);

So, the last line of the above snippet is never reached. For example, one of the interim value of 'random' is {11418080784537914682748476441522166784450220563706478273248511468872527134461311704159292539582730056378437593943246046979683371162861168931412434359870343753313063761668763145482468097049355639155174971010549311299263709538511758348493572326615870702728794915949446197591253789875233469981445511393190886679666973010087318901181571099756062605800965762790946836058337876761225162395943605452830281748916578095205254870049943949371102834858368420377983315216778020263245976878674266329346233719766832556150688583309597452671957264592075742405361892972711015149550222832829038825776608484705180542684544289251109119265}

My code is:

            var connectionInfo = new PrivateKeyConnectionInfo(_host, _loginName, new PrivateKeyFile(File.OpenRead(@"c:\Documents and Settings\Administrator\ssh\id_rsa")));
            connectionInfo.Timeout = TimeSpan.FromSeconds(30);
            using (var sftp = new SftpClient(connectionInfo))
            {
                Console.Write("Connecting " + _host + " ...");
                sftp.Connect();
                Console.WriteLine("OK");

The referenced id_rsa file looks like this:

-----BEGIN RSA PRIVATE KEY-----
MIICWQIBAAKBgQChGBhxYiDWHlpNEyFj8+2wxIflPg8ibd3KSYhwD9Tgm/WSSxK0
........
c+C+RJ41Qo14vQa6m4zxNiL3/J1DxnohPtRQArM=
-----END RSA PRIVATE KEY-----

Password connection works good.

Please note that I have no problems with the key authentication using other libraries and utilities.

Could you please help?

Thanks,
Anatoli 

Coordinator
Aug 25, 2011 at 12:22 PM

Yes,

 

I will take a look but since I didnt have many test cases when I was developing RSACipher I could check all possibilities.

What probably happens here is the 256 size is too big.

Can you send me the value of the this._key.Modulus ?

I suspect in my case it was occupying 256 bytes, I suspect in your case its less, that's why it never gets out of the loop.

So as temporary solution for your case I would decrease 256 array size to smaller that equals number of bytes occupied by Modulus.

 

Hope it helps,

Thanks,

Oleg

Coordinator
Aug 25, 2011 at 6:01 PM

I made some changes to the random number generation,

Can you please download lateset source change set and see if it works for you?

 

Thanks,

Oleg

Aug 26, 2011 at 9:38 AM
Edited Aug 26, 2011 at 10:40 AM

Now I'm getting "User cannot be authenticated." exception.

  at Renci.SshNet.Session.Connect() in D:\kaa\C#\Renci.SshNet\Session.cs:line 535   at Renci.SshNet.BaseClient.Connect() in D:\kaa\C#\Renci.SshNet\BaseClient.cs:line 104   at TestConsoleApplication.Program.Main(String[] args) in D:\kaa\C#\TestConsoleApplication\Program.cs:line 31   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)   at System.Threading.ThreadHelper.ThreadStart()

I checked again - the key works with the server with other apps.

this._key.Modulus = {113124140206341443688271190208512526707611099347002030890795872881021406617023300317097785456505441868855241658207094783318656257882579271017363205443335854191103938256828112956887414188638661348241014238903721989852264407299778933808574400159523192752366149129133930281376024269652051152394390816676723416143}

Thanks,
Anatoli 

Coordinator
Aug 26, 2011 at 1:24 PM

Hmm,

 

I just put your value in my code and it work.

 

Can you tell me what it calculates as a bitlength in this area or what bytesArray size it creates?

 

                var bitLength = max.BitLength;

                var bytesArray = new byte[bitLength / 8 + (((bitLength & 8) > 0) ? 1 : 0)];

Thanks,

Oleg

Aug 29, 2011 at 6:12 AM

bitLength = 1024

bytesArray = {byte[128]}

Aug 29, 2011 at 10:53 AM

Did you mean 7 instead of 8?

(bitLength & 8) > 0
Or either (bitLength % 8)

Coordinator
Aug 31, 2011 at 12:57 AM

ops, sorry I meant bitLength % 8, will fix it now.

It can work now, since it wil never create greater rundom number that allowed anyway, it just can take a little bit longer :(

Aug 31, 2011 at 8:47 AM

Change Set 10035 works for me :) 
Many thanks!