简体   繁体   中英

problems with RSA decryption formula

I'm trying to decrypt a message that was encrypted using the RSA algorithm

在此处输入图片说明

The example from above is taken from Website , so I tried to implement it in C#:

int msg = 67;

int Ee = 5;
int Nn = 91;
int Dd = 29;

var cipher = Math.Pow(msg, Ee) % Nn;
var msg2 = Math.Pow(cipher, Dd) % Nn;

MessageBox.Show("Msg: " + msg.ToString() + " cipher: " + cipher.ToString() 
                   + " msg: " + msg2.ToString());

And the output is following:

Msg: 67 cipher: 58 msg: 45

As you can see - encryption works fine, but decryption isn't!

So I went and inspected the website and it turned out that Javaspript uses another formula:

function mod( m, n )
{           
    return m - n*Math.floor(m/n)
}
function PowerMod(x,p,N)
    // Compute x^p mod N
    {
        var A = 1
        var m = p
        var t = x

        while( m > 0 )
        {
            k = Math.floor( m/2 )
            r = m - 2*k
            if( r == 1 )
                A = mod( A*t, N )
            t = mod( t*t, N )
            m = k
        }           
        return A
    }

        var temp = ""
        var e = form.e.value
        var d = form.d.value
        var N = form.N.value
        var M = form.Msg.value

        form.Cipher.value = PowerMod(M,e,N)

        var C = form.Cipher.value
        form.Decipher.value = PowerMod(C,d,N)

Rather than copying and pasting ready formula - I'd like to know why my approach isn't working and i'd rather fix my formula than just rewrite JS. Any ideas on how to fix decryption?

Your logic is correct, but Math.Pow() won't yield a precise result because 58 29 is too large for it to handle. This is what ultimately breaks your algorithm. In practice, RSA keys are much larger than that, and computing b ^ e is simply not feasible.

The PowerMod() JavaScript function performs modular exponentiation ( b ^ e % m ) without loss of precision using the right-to-left binary method, which is why it works.

You can read more about it on Wikipedia article for modular exponentiation .

The cipher text is 58, and your decipher key is 29.

58^29 = really, really huge. Approximately 1.378516 * 10^51

I think your direct approach is overrunning the precision of the double data type used in Math.Pow. For a modulus divide, it's the least significant bits that matter the most, and those are precisely the ones that are being ignored/lost.

It looks to me like the javascript algorithm is collapsing the power operation and the mod operation together so the data always stays within easy reach of the precision of the underlying data types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM