如何计算D代表从P,Q和E RSA加密 [英] How to calculate D for RSA encryption from P,Q and E

查看:307
本文介绍了如何计算D代表从P,Q和E RSA加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找到 D 使用 P 问:电子压差的Dq (P 1 模Q)可太)。

根据这个答案和的这个答案并更新这个问题使用下面的方法,我应该得到 D

要测试这个我生成的密钥对,并试图从现有的计算组件和比较的结果与原件。所有的成绩都不错,除了 D 。有什么毛病我的计算,我从上面的答案复制。 这将是巨大的,如果有人能告诉我什么,我做错了。

测试code

 使用系统;
使用System.Numerics;
使用System.Security.Cryptography;
使用System.Text;

类节目{

    静态RSAParameters键=新RSAParameters(){
        P =新的字节[] {
                写0xDE,0xA6,0x35,0x0B中,0x0A的,0xA5的,0xD7,0XA0,0x5c的,0x49,0xEA,0xD1,0x3F的,0xA6,0xF5,0×12,
                的0x19,0×06,0x25,0x8A,0xD9,0xA7,0×07,0xE7,0X0D,0x8A,0x7C,0xB1,0xD4,0×81,0x64,是0xFD,
                0×04,0xEC,0X47,0x33,0x42后,0x0B中,输入0x22,0xF2,地址0x60,为0xBB,0x75,0X62,0x53,0x3E的,0x​​1A的,0x97,
                0x9D,0xEF,0x25,0xA7,为0xE5,0X24,0x3A的为0x30,0x36数据,0xA5的,0xF9,0x8A,0xF5,0xFF时,0x1D,0x1B
            },

        Q =新的字节[] {
                0xBE,0xB9,地址0x60,0×12,0×05,0xB1,0x61,0xD9,输入0x22,为0xD8,的0x84,0x6E,0x9A执行,0x7B,0xD1,0x9B,
                0x17已,0xA5的,0xDD,0X02,0x5E,0x9D,为0xD8,0X24,0×06,0x1B,0xF3,为0xD8,值为0x2F,x79的,0xFE时,0x78,
                0x74,0x3D之间,0xC4,0xE6,0x17已,0xD2,0xB7,0x68,0x78,0x6F,0x53,取0xE0,0x38,0x00时,0x86可以,0xFB的才能,
                为0x20,0x2A,0x1B,0xBD,0x91的信息,0x76,0x3E的,0x​​33,0x85未,0x9A执行,0X31,0xE6,均为0x88,地址0x60,0x91的信息,0x81表示
            },

        DP =新的字节[] {
                0xAC,0x28,0x92,0x6D,0×46,的0x3F,0x74,0x1A的,0XA0,为0x21,0xDB,为0xBB,为0x0E,0xDF,0xD7,0X31,
                0xB6,0x3D之间,0xC5,0x7B,0xB6,0xCE,0x6B,0xD2,0xE1,0xEA,0x8A,0x7E的,和0xAA,0xD5,0x9E,0xB3,
                0xF2,0×41,0x8C,0xD0,0x7A,0xA9,0xC7,的0xCC,0xE8,0xB5执行,0x2A,0x8F,将0xEB,0xD3,0xE2,0x96,
                0×07,0xDD,0xEA,0x1D,0×07,0x96,5AH即可,0x93,0xFB的才能,0x3D之间,0x9D,0x56,为0x30,写0xDE,0xA1,0xAF执行
            },

        DQ =新的字节[] {
                0xA6,为0x9c,0x44,0x1B,0x9A执行,0x53,0x89上,0xD9,0xE8,0xC1,0xE2,0x76,0xC8,87H的,0x6F,为0xE5,
                为0x1F,0x74,的0x6A,0xAC,0x5E,0×41,0x5F的,0x86可以,0XA0,为0xBB,为0x9c,x79的,0xF7,87H的,87H的,0xD0,
                0x6C,0x23,0x65,0xB5执行,0x67,0x8C,0x51,0X62,0x77,0x0B中,0X31,0xE7,0x86可以,0xA4,0x97,0×46,
                0x1B,0xA4,0X0D,写入0x55,0xBE,0x13,取0xE0,0x64,0x9B,0xCA,0xC6,0xDA,0xCF,0xBA,0X24,0x81表示
            },

        InverseQ =新的字节[] {
                0×02,的0x42,0x90处,0xAE,为0xFF,0xFE的,0x​​B6,0xCB,0x53,0xFF时,0x96,0x17已,0xC6,0xE4,0x3F的,0xE6,
                0xC7,0xBC,0xB2,将0xEB,0x53,0xA9,0X47,0xEE,为0x10,0x36数据,0x98在全局,0xEF,0xA8,0x3E的,为0x9c,0xF7,
                0xF9,0xCF,0X24,为0xE5,0xD7,0x9A执行,0xAF执行,×09,0xCF,0x28,和0xAA,0x5D,0x2A,0xB7,0x27(0x73)的,
                0X47,0x2D,0x54,0x54,0x61,0xC5,0xCE,0x3E的,0x​​A4,0x91的信息,0xF6,0x9D,0xF4中,0x65,0x08的,0xDD
            },

        指数=新的字节[] {
                0×00,0×01,0×00,0×01,
            },

        模量=新的字节[] {
                0xA5的,取0xE0,位0x95,0x08的,87H的,0×69,0x2B访问,0xB4,0x7F的,0x08的,0xFB的才能,0x4F,0x66,0x85未,0xD9,位0x95,
                0x53,为0x0F,0x7C,0x99,位0x95,为0x16,0xF4中,0X0D,写入0xAD,0x9E,0X31,为0xD8,为0x20,0xF4中,均为0x88,0x63,
                0xAE,0x51,0x04的为0xC2,0xE9,0x92,0x3C符号,为0x1C,0×90,0xF8时,0xF4中,0x38,的0x6A,0x86可以,是0xFD,0x8F,
                写0xDE,0x85未,输入0x22,0xDD,0xE8,0x7E的,0x​​8D,0xF2,0xC5,0xC9,0x4E,0x71,0x2B访问,0x56,0x25,0x1A的,
                0xEA,0x66,0x15,的0x19,0x63,0x70,0x53,x79的,0xDF,0x38,0x49,为0x30,0x74,×45,0xBE,0xA3执行,
                0x28,0X0D,为0x0E,0x7A,0x7D,0xB6,0x8B,0xCA,×09,0x56,0×21,0xE7,0x98在全局,0x3E的,0x​​4B,0x8B,
                0xD0,0X31,0x27,为0x8E,0x6F,0x10的,0xA6,0x6C,为0x1C,0x48,0xB5执行,0x5E,0x89上,0x7B,0x74,0x74,
                0xB2,0×57,0x72,0x6D,为0x18,将0xEB,0xF3,0xF5,0x53,0xCA,0x8C,0xBE,0xB7,0x29,0xF5,0x9B
            },

        D =新的字节[] {
                0x9F,0x86可以,0xE1,送出0x4d,0x96,0x8C,0xFA回应,0xCF,0×57,0xED,0x17已,0x64,0x41既,0×41,0X31,0×04,
                0x7F的,0×21,×41,为0xBF,0xA2,0xB6,0xB4,0x78,0×03,0x25,0x44,0xE2,0x8A,0xAF执行,输入0x22,0x0C的,
                0x5B,0xB4,0xE7,0x53,0x5c的,0xB6,0x9A执行,0xC1,为0x0E,0x5B,0x9E,0xE4,0x32,0xEF,0x28,0X24,
                0x98在全局,0xE8,0x89上,0xA3执行,0xC8,0xD9,0X0D,0×43,×12,为0x1C,0x8C,0x28,输入0x22,x79的,0x72,0xAC,
                0x66,0x7B,0x7D,0xD2,0xF9,0x48,0×06,0XCD,0x9D,0x9A执行,0xE6,0x42后,0x92,0xBA,0x56,0xA6,
                0x63,0x07执行,0X1E,0x25,0x4E,0xC8,0x07执行,将0x58,0x5B,均为0x88,地址0x60,0x97,0x92,0xE2,0xD5,0xB9,
                0xC6,0x70,为0xBB,0x63,5AH即可,0xC3,0xC3,0xA6,0×46,5AH即可,为0x1C,为0x9c,为0xBF,0x61,0×57,0x9E,
                0x9E,0xFA回应,为0xC0,0xC4,0x8A,为0xC2,0xBA,均为0x88,将0x46,0xA9,0x7A,0xF2,0x7D,0x4F,0x6C,0×01
            }
    };

    公共静态的BigInteger FromBigEndian(byte []的P){
        Array.Reverse(对);
        如果(对[p.Length  -  1]≥127){
            Array.Resize(参考磷,p.Length + 1);
            P [p.Length  -  1] = 0;
        }
        返回新的BigInteger(P);
    }

    静态无效的主要(字串[] args){

        使用(的RSACryptoServiceProvider RS​​A =新的RSACryptoServiceProvider(){PersistKeyInCsp = FALSE}){
            rsa.ImportParameters(键);

            Console.Write(测试加密/解密......);
            字符串消息=测试一些加密数据;
            byte []的缓冲区= Encoding.ASCII.GetBytes(消息);
            byte []的EN codeD = rsa.Encrypt(缓冲,真正的);
            byte []的德codeD = rsa.Decrypt(EN codeD,真正的);
            字符串MESSAGE1 = ASCIIEncoding.ASCII.GetString(德codeD);

            如果(消息== MESSAGE1){
                Console.WriteLine(好:));
            } 其他 {
                Console.WriteLine(坏加密:();
                Console.ReadKey();
                返回;
            }
        }

        //转换关键BigIntegers
        BigInteger的P = FromBigEndian(key.P);
        BigInteger的Q = FromBigEndian(key.Q);
        BigInteger的DP = FromBigEndian(key.DP);
        BigInteger的DQ = FromBigEndian(key.DQ);
        BigInteger的InverseQ = FromBigEndian(key.InverseQ);
        BigInteger的E = FromBigEndian(key.Exponent);
        BigInteger值M = FromBigEndian(key.Modulus);
        BigInteger的D = FromBigEndian(key.D);


        Console.WriteLine(测试号......);
        的BigInteger M1 = BigInteger.Multiply(P,Q); // M = P * Q
        如果(M1.CompareTo(M)== 0){
            Console.WriteLine(M好:));
        } 其他 {
            Console.WriteLine(坏中号:();
            Console.ReadKey();
            返回;
        }

        BigInteger的PMinus1 = BigInteger.Subtract(P,BigInteger.One); // M = P * Q
        BigInteger的DP1 = BigInteger.Remainder(D,PMinus1); // M = P * Q
        如果(DP1.CompareTo(DP)== 0){
            Console.WriteLine(DP好:));
        } 其他 {
            Console.WriteLine(坏DP :();
            Console.ReadKey();
            返回;
        }

        BigInteger的QMinus1 = BigInteger.Subtract(Q,BigInteger.One); // M = P * Q
        BigInteger的DQ1 = BigInteger.Remainder(D,QMinus1); // M = P * Q
        如果(DQ1.CompareTo(DQ)== 0){
            Console.WriteLine(DQ好:));
        } 其他 {
            Console.WriteLine(坏DQ :();
            Console.ReadKey();
            返回;
        }

        BigInteger的披= BigInteger.Multiply(PMinus1,QMinus1);
        BigInteger的PhiMinus1 = BigInteger.Subtract(披,BigInteger.One);
        BigInteger的D1 = BigInteger.ModPow(E,PhiMinus1,披);
        如果(D1.CompareTo(D)== 0){
            Console.WriteLine(D好:));
        } 其他 {
            Console.WriteLine(出错的D :();
            Console.ReadKey();
            返回;
        }

        Console.ReadKey();
    }
}
 

测试结果

 测试加密/解密...好:)
测试号码...
  中号好了:)
  DP好:)
  DQ好:)
  出错的D :(
 

解决方案

首先,你需要确认 GCD(E,φ)= 1 ,因为ð只有在该属性保存存在。然后计算电子模<$ C的模反元素$ C>披 我描述我在C#1 / BigInteger的答案

您code似乎认为 E ^(φ(N)-1)模φ(N)是逆,但是这是不正确。我认为正确的公式应该为 E ^(φ(φ(N)) - 1)模φ(N),但这是使用不方便,因为你只知道φ(N)而不是φ(φ(N))

我建议使用扩展欧几里德算法被移植维基百科的伪code到C#。


作为一个侧面说明:的有用于 D ,因为你不需要电子邮件往往是多重的等效值* D模φ(N)= 1 只是 * D + Emodλ(N)= 1 其中λ是的卡迈克尔功能看到<一href="http://crypto.stackexchange.com/questions/1789/why-rsa-encryption-key-is-based-on-modulophin-rather-than-modulo-n">"Why RSA加密密钥基于模(披(n))的,而不是在crypto.SE 的模N

I am trying to find D using P,Q and E (Dp, Dq and (p-1mod q) are available too).

According to this answer and this answer and update for this question using following method I should get D.

To test this I generated Key pair and tried to calculate components from existing ones and compare the result with originals. All the results are good except for D. there is something wrong with my calculation which I copied from above answers. it would be great if someone can tell me what I'm doing wrong.

Test Code

using System;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;

class Program {

    static RSAParameters key = new RSAParameters() {
        P = new byte[]{
                0xDE, 0xA6, 0x35, 0x0B, 0x0A, 0xA5, 0xD7, 0xA0, 0x5C, 0x49, 0xEA, 0xD1, 0x3F, 0xA6, 0xF5, 0x12, 
                0x19, 0x06, 0x25, 0x8A, 0xD9, 0xA7, 0x07, 0xE7, 0x0D, 0x8A, 0x7C, 0xB1, 0xD4, 0x81, 0x64, 0xFD, 
                0x04, 0xEC, 0x47, 0x33, 0x42, 0x0B, 0x22, 0xF2, 0x60, 0xBB, 0x75, 0x62, 0x53, 0x3E, 0x1A, 0x97, 
                0x9D, 0xEF, 0x25, 0xA7, 0xE5, 0x24, 0x3A, 0x30, 0x36, 0xA5, 0xF9, 0x8A, 0xF5, 0xFF, 0x1D, 0x1B
            },

        Q = new byte[]{
                0xBE, 0xB9, 0x60, 0x12, 0x05, 0xB1, 0x61, 0xD9, 0x22, 0xD8, 0x84, 0x6E, 0x9A, 0x7B, 0xD1, 0x9B, 
                0x17, 0xA5, 0xDD, 0x02, 0x5E, 0x9D, 0xD8, 0x24, 0x06, 0x1B, 0xF3, 0xD8, 0x2F, 0x79, 0xFE, 0x78, 
                0x74, 0x3D, 0xC4, 0xE6, 0x17, 0xD2, 0xB7, 0x68, 0x78, 0x6F, 0x53, 0xE0, 0x38, 0x00, 0x86, 0xFB, 
                0x20, 0x2A, 0x1B, 0xBD, 0x91, 0x76, 0x3E, 0x33, 0x85, 0x9A, 0x31, 0xE6, 0x88, 0x60, 0x91, 0x81
            },

        DP = new byte[]{
                0xAC, 0x28, 0x92, 0x6D, 0x46, 0x3F, 0x74, 0x1A, 0xA0, 0x21, 0xDB, 0xBB, 0x0E, 0xDF, 0xD7, 0x31, 
                0xB6, 0x3D, 0xC5, 0x7B, 0xB6, 0xCE, 0x6B, 0xD2, 0xE1, 0xEA, 0x8A, 0x7E, 0xAA, 0xD5, 0x9E, 0xB3, 
                0xF2, 0x41, 0x8C, 0xD0, 0x7A, 0xA9, 0xC7, 0xCC, 0xE8, 0xB5, 0x2A, 0x8F, 0xEB, 0xD3, 0xE2, 0x96, 
                0x07, 0xDD, 0xEA, 0x1D, 0x07, 0x96, 0x5A, 0x93, 0xFB, 0x3D, 0x9D, 0x56, 0x30, 0xDE, 0xA1, 0xAF
            },

        DQ = new byte[]{
                0xA6, 0x9C, 0x44, 0x1B, 0x9A, 0x53, 0x89, 0xD9, 0xE8, 0xC1, 0xE2, 0x76, 0xC8, 0x87, 0x6F, 0xE5, 
                0x1F, 0x74, 0x6A, 0xAC, 0x5E, 0x41, 0x5F, 0x86, 0xA0, 0xBB, 0x9C, 0x79, 0xF7, 0x87, 0x87, 0xD0, 
                0x6C, 0x23, 0x65, 0xB5, 0x67, 0x8C, 0x51, 0x62, 0x77, 0x0B, 0x31, 0xE7, 0x86, 0xA4, 0x97, 0x46, 
                0x1B, 0xA4, 0x0D, 0x55, 0xBE, 0x13, 0xE0, 0x64, 0x9B, 0xCA, 0xC6, 0xDA, 0xCF, 0xBA, 0x24, 0x81
            },

        InverseQ = new byte[]{
                0x02, 0x42, 0x90, 0xAE, 0xFF, 0xFE, 0xB6, 0xCB, 0x53, 0xFF, 0x96, 0x17, 0xC6, 0xE4, 0x3F, 0xE6, 
                0xC7, 0xBC, 0xB2, 0xEB, 0x53, 0xA9, 0x47, 0xEE, 0x10, 0x36, 0x98, 0xEF, 0xA8, 0x3E, 0x9C, 0xF7, 
                0xF9, 0xCF, 0x24, 0xE5, 0xD7, 0x9A, 0xAF, 0x09, 0xCF, 0x28, 0xAA, 0x5D, 0x2A, 0xB7, 0x27, 0x73, 
                0x47, 0x2D, 0x54, 0x54, 0x61, 0xC5, 0xCE, 0x3E, 0xA4, 0x91, 0xF6, 0x9D, 0xF4, 0x65, 0x08, 0xDD
            },

        Exponent = new byte[]{
                0x00, 0x01, 0x00, 0x01, 
            },

        Modulus = new byte[]{
                0xA5, 0xE0, 0x95, 0x08, 0x87, 0x69, 0x2B, 0xB4, 0x7F, 0x08, 0xFB, 0x4F, 0x66, 0x85, 0xD9, 0x95, 
                0x53, 0x0F, 0x7C, 0x99, 0x95, 0x16, 0xF4, 0x0D, 0xAD, 0x9E, 0x31, 0xD8, 0x20, 0xF4, 0x88, 0x63, 
                0xAE, 0x51, 0x04, 0xC2, 0xE9, 0x92, 0x3C, 0x1C, 0x90, 0xF8, 0xF4, 0x38, 0x6A, 0x86, 0xFD, 0x8F, 
                0xDE, 0x85, 0x22, 0xDD, 0xE8, 0x7E, 0x8D, 0xF2, 0xC5, 0xC9, 0x4E, 0x71, 0x2B, 0x56, 0x25, 0x1A, 
                0xEA, 0x66, 0x15, 0x19, 0x63, 0x70, 0x53, 0x79, 0xDF, 0x38, 0x49, 0x30, 0x74, 0x45, 0xBE, 0xA3, 
                0x28, 0x0D, 0x0E, 0x7A, 0x7D, 0xB6, 0x8B, 0xCA, 0x09, 0x56, 0x21, 0xE7, 0x98, 0x3E, 0x4B, 0x8B, 
                0xD0, 0x31, 0x27, 0x8E, 0x6F, 0x10, 0xA6, 0x6C, 0x1C, 0x48, 0xB5, 0x5E, 0x89, 0x7B, 0x74, 0x74, 
                0xB2, 0x57, 0x72, 0x6D, 0x18, 0xEB, 0xF3, 0xF5, 0x53, 0xCA, 0x8C, 0xBE, 0xB7, 0x29, 0xF5, 0x9B
            },

        D = new byte[]{
                0x9F, 0x86, 0xE1, 0x4D, 0x96, 0x8C, 0xFA, 0xCF, 0x57, 0xED, 0x17, 0x64, 0x41, 0x41, 0x31, 0x04, 
                0x7F, 0x21, 0x41, 0xBF, 0xA2, 0xB6, 0xB4, 0x78, 0x03, 0x25, 0x44, 0xE2, 0x8A, 0xAF, 0x22, 0x0C, 
                0x5B, 0xB4, 0xE7, 0x53, 0x5C, 0xB6, 0x9A, 0xC1, 0x0E, 0x5B, 0x9E, 0xE4, 0x32, 0xEF, 0x28, 0x24, 
                0x98, 0xE8, 0x89, 0xA3, 0xC8, 0xD9, 0x0D, 0x43, 0x12, 0x1C, 0x8C, 0x28, 0x22, 0x79, 0x72, 0xAC, 
                0x66, 0x7B, 0x7D, 0xD2, 0xF9, 0x48, 0x06, 0xCD, 0x9D, 0x9A, 0xE6, 0x42, 0x92, 0xBA, 0x56, 0xA6, 
                0x63, 0x07, 0x1E, 0x25, 0x4E, 0xC8, 0x07, 0x58, 0x5B, 0x88, 0x60, 0x97, 0x92, 0xE2, 0xD5, 0xB9, 
                0xC6, 0x70, 0xBB, 0x63, 0x5A, 0xC3, 0xC3, 0xA6, 0x46, 0x5A, 0x1C, 0x9C, 0xBF, 0x61, 0x57, 0x9E, 
                0x9E, 0xFA, 0xC0, 0xC4, 0x8A, 0xC2, 0xBA, 0x88, 0x46, 0xA9, 0x7A, 0xF2, 0x7D, 0x4F, 0x6C, 0x01
            }
    };

    public static BigInteger FromBigEndian(byte[] p) {
        Array.Reverse(p);
        if (p[p.Length - 1] > 127) {
            Array.Resize(ref p, p.Length + 1);
            p[p.Length - 1] = 0;
        }
        return new BigInteger(p);
    }

    static void Main(string[] args) {

        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider() { PersistKeyInCsp = false }) {
            rsa.ImportParameters(key);

            Console.Write("Testing Encrypt/Decrypt ... ");
            string message = "Testing Some Data to Encrypt";
            byte[] buffer = Encoding.ASCII.GetBytes(message);
            byte[] encoded = rsa.Encrypt(buffer, true);
            byte[] decoded = rsa.Decrypt(encoded, true);
            string message1 = ASCIIEncoding.ASCII.GetString(decoded);

            if (message == message1) {
                Console.WriteLine("Ok :)");
            } else {
                Console.WriteLine("Bad Encryption :(");
                Console.ReadKey();
                return;
            }
        }

        //Convert Key to BigIntegers
        BigInteger P = FromBigEndian(key.P);
        BigInteger Q = FromBigEndian(key.Q);
        BigInteger DP = FromBigEndian(key.DP);
        BigInteger DQ = FromBigEndian(key.DQ);
        BigInteger InverseQ = FromBigEndian(key.InverseQ);
        BigInteger E = FromBigEndian(key.Exponent);
        BigInteger M = FromBigEndian(key.Modulus);
        BigInteger D = FromBigEndian(key.D);


        Console.WriteLine("Testing Numbers ... ");
        BigInteger M1 = BigInteger.Multiply(P, Q); // M = P*Q
        if (M1.CompareTo(M) == 0) {
            Console.WriteLine("  M Ok :)");
        } else {
            Console.WriteLine("  Bad M:(");
            Console.ReadKey();
            return;
        }

        BigInteger PMinus1 = BigInteger.Subtract(P, BigInteger.One); // M = P*Q
        BigInteger DP1 = BigInteger.Remainder(D, PMinus1); // M = P*Q
        if (DP1.CompareTo(DP) == 0) {
            Console.WriteLine("  DP Ok :)");
        } else {
            Console.WriteLine("  Bad DP :(");
            Console.ReadKey();
            return;
        }

        BigInteger QMinus1 = BigInteger.Subtract(Q, BigInteger.One); // M = P*Q
        BigInteger DQ1 = BigInteger.Remainder(D, QMinus1); // M = P*Q
        if (DQ1.CompareTo(DQ) == 0) {
            Console.WriteLine("  DQ Ok :)");
        } else {
            Console.WriteLine("  Bad DQ :(");
            Console.ReadKey();
            return;
        }

        BigInteger Phi = BigInteger.Multiply(PMinus1, QMinus1);
        BigInteger PhiMinus1 = BigInteger.Subtract(Phi, BigInteger.One);
        BigInteger D1 = BigInteger.ModPow(E, PhiMinus1, Phi);
        if (D1.CompareTo(D) == 0) {
            Console.WriteLine("  D Ok :)");
        } else {
            Console.WriteLine("  Bad D :(");
            Console.ReadKey();
            return;
        }

        Console.ReadKey();
    }
}

Test Result

Testing Encrypt/Decrypt ... Ok :)
Testing Numbers ...
  M Ok :)
  DP Ok :)
  DQ Ok :)
  Bad D :(

解决方案

First you need to verify that GCD(e, φ) = 1 because d only exists if that property holds. Then calculate the modular multiplicative inverse of e modulo phi which I describe in my answer to "1/BigInteger in C#".

Your code seems to assume that e^(φ(n)-1) mod φ(n) is that inverse, but that's incorrect. I think the correct formula would be e^(φ(φ(n))-1) mod φ(n), but that's inconvenient to use since you only know φ(n) but not φ(φ(n)).

I recommend using the Extended Euclidean algorithm by porting the wikipedia pseudocode to C#.


As a side-note: There are often multiple equivalent values for d since you don't need e*d mod φ(n)=1 but just e*d mod λ(n)=1 where λ is the Carmichael function see "Why RSA encryption key is based on modulo(phi(n)) rather than modulo n" on crypto.SE

这篇关于如何计算D代表从P,Q和E RSA加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆