我正在研究 RSA 算法,总的来说一切正常,但解密存在问题。对于某些数字,例如 9、10、13,消息未正确解码。
编码
private void button_GetKey_Click(object sender, EventArgs e)
{
int n = p * q; // Модуль, который используется в открытом ключе
int f = (p - 1) * (q - 1); // Функция Эйлера
List<int> simpleNumbers = generateSimpleNumbers(f);
int exp = getExponent(simpleNumbers, f);
// На данном этапе у нас есть открытый ключ {exp, n}
//Далее необхожимо сформировафть личный ключ
int d = generatePrivateKey(exp, f); // личный ключ {d, n}
// Теперь можем приступать к кодированию
Random rnd = new Random();
//Получить случайное число
double x = rnd.Next(1, n);
textBox5.Text = x.ToString();
x = Math.Pow(x, exp);
x = x % n;
textBox3.Text = x.ToString();
// После приступаем к дешифровке
double y = Math.Pow(x, d);
y = y % n;
textBox4.Text = y.ToString();
}
private bool isSimpleNumber(int n)
{
int count = 0;
for (int i = 2; i <= n; i++)
{
if (n % i == 0) count++;
}
if (count == 1)
return true;
else
return false;
}
private List<int> generateSimpleNumbers(int n)
{
int count;
List<int> numbers = new List<int>();
for (int i = 2; i < n; i++)
{
count = 0;
for (int j = 2; j <= i; j++)
{
if (i % j == 0) count++;
}
if (count == 1)
numbers.Add(i);
}
return numbers;
}
// Находим экспоненту
private int getExponent(List<int> numbers, int fi)
{
foreach (int el in numbers)
{
if (fi % el != 0)
return el;
}
return 0;
}
// Находим личный ключ
private int generatePrivateKey(int e, int fi)
{
int d = e;
int test = 0;
do
{
d += 1;
test = (d * e) % fi;
} while (!isSimpleNumber(d) || test != 1);
return d;
}
为什么解密在某些时候会被破坏?毕竟,没有违反条件(x < n)。基于此来源
您查找密钥的算法错误。
我的版本也不是最佳的,但很简单。对于复杂的选项,您在这里- 我从那里获取了有关 RSA 的所有信息。
一般来说,您需要以一种好的方式使用大数字(例如 1024 位),否则您可能会出现溢出,并且您的所有数据都将付诸东流。