Отображение параметров шифрования RSA из CRT (китайская теорема об остатках) в формат.NET
Мне нужно реализовать шифрование / дешифрование RSA с использованием C#
У меня есть закрытый ключ со следующими параметрами:
mod n
, exponent
, p
, q
, dP
, dQ
, а также (p
-1
mod q)
Выше параметры объясняются в китайском алгоритме остатка
Однако реализация RSA на C#.NET имеет другой набор параметров:
Modulus
, Exponent
, P
, Q
, DP
, DQ
, D
, InverseQ
Когда я пытаюсь отобразить данные из CRT
в DOTNET
Я получаю ошибку Bad Data
За p
, q
, dP
а также dQ
отображение очевидно, но в отношении остальных параметров я не уверен.
Было бы здорово, если бы я мог получить помощь в картировании этих параметров
3 ответа
mod n
карты для Modulus
, p
-1
mod q
карты для InverseQ
, показатель шифрования отображается на Exponent
и показатель дешифрования отображается на D
,
Показатель шифрования e
и показатель расшифровки d
связаны e*d = 1 mod (p-1)(q-1). Таким образом, если у вас есть один из них, вы можете легко получить другой, используя несколько методов из класса System.Numerics.BigInteger.
var Pminus1 = BigInteger.Subtract(P, BigInteger.One);
var Qminus1 = BigInteger.Subtract(Q, BigInteger.One);
var Phi = BigInteger.Multiply(Pminus1, Qminus1);
var PhiMinus1 = BigInteger.Subtract(Phi, BigInteger.One);
// var D = BigInteger.ModPow(E, PhiMinus1, Phi);
Обратите внимание, что при создании.NET BigInteger необходимо соблюдать осторожность, особенно если вы привыкли к классу Java BigInteger. Смотрите этот вопрос для получения дополнительной информации.
РЕДАКТИРОВАТЬ:
Как указывает CodeInChaos, последняя строка НЕПРАВИЛЬНА!
НЕПРАВИЛЬНО! НЕПРАВИЛЬНО! НЕПРАВИЛЬНО!
Я смущен. В поклоне силам зла класс BigInteger не имеет ни модульного обратного метода, ни метода расширенных евклидовых алгоритмов. Тем не менее, вы можете найти в Google "C# расширенный евклидов алгоритм", вы можете найти много реализаций. Расширенный евклидов алгоритм дает целые числа x и y такие, что 1 = e*x + phi * y. x является обратной величиной e mod phi, поэтому необходимо установить D = x mod phi.
Расширенный Евклидов алгоритм может быть использован для вычисления модульного обратного, в этом случае будет рассчитываться D, используйте эту ссылку: http://www.di-mgt.com.au/euclidean.html, чтобы получить подробности, я проверял исходный код на C#, как показано ниже, и результат совпадает,
public static BigInteger modinv(BigInteger u, BigInteger v)
{
BigInteger inv, u1, u3, v1, v3, t1, t3, q;
BigInteger iter;
/* Step X1. Initialise */
u1 = 1;
u3 = u;
v1 = 0;
v3 = v;
/* Remember odd/even iterations */
iter = 1;
/* Step X2. Loop while v3 != 0 */
while (v3 != 0)
{
/* Step X3. Divide and "Subtract" */
q = u3 / v3;
t3 = u3 % v3;
t1 = u1 + q * v1;
/* Swap */
u1 = v1; v1 = t1; u3 = v3; v3 = t3;
iter = -iter;
}
/* Make sure u3 = gcd(u,v) == 1 */
if (u3 != 1)
return 0; /* Error: No inverse exists */
/* Ensure a positive result */
if (iter < 0)
inv = v - u1;
else
inv = u1;
return inv;
}
D можно рассчитать так:
var qq = BigInteger.Multiply(phi, n);
var qw = BigInteger.Multiply(phi, qq);
BigInteger D = BigInteger.ModPow(e, (qw - 1), phi);