Click here to Skip to main content
15,891,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have the C# code that does encryption with RSA algorithm but I want to give my own p and q, when I try to give for instance; p=11 q=5 manually. When I try to set my values manually inside Create() method, it gives me error at ModInverse() saying System.ArgumentException: 'a is not convertible.'

What I have tried:

public void RSACompatibility()
        {
            var rsa = new RSACryptoServiceProvider(512);
            var parameters = rsa.ExportParameters(true);

            var recreatedParameters = Create(parameters.P, parameters.Q, parameters.Exponent, parameters.Modulus);
            var recreatedRSA = new RSACryptoServiceProvider();
            recreatedRSA.ImportParameters(recreatedParameters);

            byte[] message = Encoding.UTF8.GetBytes("hello");
            var ciphertext = rsa.Encrypt(message, false);
            var plaintext = recreatedRSA.Decrypt(ciphertext, false);
            string recreatedMessage = Encoding.UTF8.GetString(plaintext);

            var bw = new BinaryWriter(File.Open("path", FileMode.OpenOrCreate));
            bw.Write(ciphertext);
        }

        private static RSAParameters Create(byte[] p, byte[] q, byte[] exponent, byte[] modulus)
        {
            //set number to byte array
            int intValueP = 51;
            int intValueQ = 7;
            byte[] intBytes = BitConverter.GetBytes(intValueP);
            byte[] intBytes2 = BitConverter.GetBytes(intValueQ);
            var addlParameters = GetFullPrivateParameters(
                p: new BigInteger(CopyAndReverse(intBytes)),
                q: new BigInteger(CopyAndReverse(intBytes2)),
                e: new BigInteger(CopyAndReverse(exponent)),
                modulus: new BigInteger(CopyAndReverse(modulus)));

            return new RSAParameters
            {
                P = p,
                Q = q,
                Exponent = exponent,
                Modulus = modulus,
                D = addlParameters.D,
                DP = addlParameters.DP,
                DQ = addlParameters.DQ,
                InverseQ = addlParameters.InverseQ,
            };
        }

        private static RSAParameters GetFullPrivateParameters(BigInteger p, BigInteger q, BigInteger e, BigInteger modulus)
        {
            
            var n = p * q;
            var phiOfN = n - p - q + 1; // OR: (p - 1) * (q - 1);

            var d = ModInverse(e, phiOfN);
            

            var dp = d % (p - 1);
            var dq = d % (q - 1);

            var qInv = ModInverse(q, p);
          

            return new RSAParameters
            {
                D = CopyAndReverse(d.ToByteArray()),
                DP = CopyAndReverse(dp.ToByteArray()),
                DQ = CopyAndReverse(dq.ToByteArray()),
                InverseQ = CopyAndReverse(qInv.ToByteArray()),
            };
        }

        private static BigInteger Encrypt(BigInteger m, BigInteger n, BigInteger e)
        {
            return BigInteger.ModPow(m, e, n);
        }

        private static BigInteger Decrypt(BigInteger mEnc, BigInteger d, BigInteger n)
        {
            return BigInteger.ModPow(mEnc, d, n);
        }


        public static BigInteger ModInverse(BigInteger a, BigInteger n)
        {
            BigInteger t = 0, nt = 1, r = n, nr = a;

            if (n < 0)
            {
                n = -n;
            }

            if (a < 0)
            {
                a = n - (-a % n);
            }

            while (nr != 0)
            {
                var quot = r / nr;

                var tmp = nt; nt = t - quot * nt; t = tmp;
                tmp = nr; nr = r - quot * nr; r = tmp;
            }

            if (r > 1) throw new ArgumentException(nameof(a) + " is not convertible.");
            if (t < 0) t = t + n;
            return t;
        }

        private static byte[] CopyAndReverse(byte[] data)
        {
            byte[] reversed = new byte[data.Length];
            Array.Copy(data, 0, reversed, 0, data.Length);
            Array.Reverse(reversed);
            return reversed;
        }
Posted
Comments
Richard MacCutchan 1-Aug-19 6:41am    
It is your code that is throwing the error message. Use your debugger to find out how it gets to that point. Your code would also be easier to understand if you used proper variable names rather than single letters.
Danny96 1-Aug-19 8:04am    
I am on it, trying

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900