10

PとQの値が、.NetRSAParametersのモジュラスの値と一致しません。RSAアルゴリズムとMSDNドキュメントによると、次のようになります。P *Q=モジュラス

512ビットのRSAキーペアを生成し、次を呼び出してXMLにエクスポートしました。

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
rsa.ToXmlString(true);

これにより、次のXMLが得られました。

<RSAKeyValue>
  <Modulus>rcLI1XTfmXtX05zq67d1wujnUvevBu8dZ5Q5uBUi2mKndH1FZLYCKrjFaDTB/mXW1l5C74YycVLS6msY2NNJYw==</Modulus>
  <Exponent>AQAB</Exponent>
  <P>1dwGkK5POlcGCjQ96Se5NSPu/hCm8F5EYwyqRpLVzgk=</P>
  <Q>0AAEMHBj7CP2XHfCG/RzGldw1GdsW13rTo3uEE9Dtws=</Q>
  <DP>PO4jMLV4/TYuElowCW235twGC3zTE0jIUzAYk2LiZ4E=</DP>
  <DQ>ELJ/o5fSHanBZCjk9zOHbezpDNQEmc0PT64LF1oVmIM=</DQ>
  <InverseQ>NyCDwTra3LiUin05ZCGkdKLwReFC9L8Zf01ZfYabSfQ=</InverseQ>
  <D>EWwFTPmx7aajULFcEJRNd2R4xSXWY8CX1ynSe7WK0BCH42wf/REOS9l8Oiyjf587BhGa3y8jGKhUD7fXANDxcQ==</D>
</RSAKeyValue>

これで、データの暗号化、復号化、署名、検証を行うための小さなテストプログラムを作成することに成功しました。

最後に、小さなテストコードを追加しました。

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
rsa.FromXmlString(key); // key = string with XML above

RSAParameters param = rsa.ExportParameters(true);
BigInteger p = new BigInteger(param.P);
BigInteger q = new BigInteger(param.Q);
BigInteger n = new BigInteger(param.Modulus);
BigInteger myN = BigInteger.Multiply(p, q);
Console.WriteLine("n   = " + n.ToString());
Console.WriteLine("myN = " + myN.ToString());

これにより、次の出力が得られました。

n   = 5200154866521200075264779234483365112866265806746380532891861717388028374942014660490111623133775661411009378522295439774347383363048751390839618325234349

myN = 23508802329434377088477386089844302414021121047189424894399694701810500376591071843028984420422297770783276119852460021668188142735325512873796040092944

PとQの乗算がモジュラスと等しくないのはなぜですか?

エンディアン、エンコーディング、BigIntegerクラス、正常に暗号化、復号化、署名、上記のXMLキーによる検証など、すでに多くのことを確認しましたが、PとQの乗算がモジュラスと等しくない理由の説明が見つかりません...

P * Qがモジュラスではない理由を誰かが説明するのを手伝ってもらえますか?

読み取り可能な形式のすべての値:

Modulus  = 5200154866521200075264779234483365112866265806746380532891861717388028374942014660490111623133775661411009378522295439774347383363048751390839618325234349
Exponent = 65537
P  = 4436260148159638728185416185189716006279182659244174640493183003717504785621
Q  = 5299238895894527538601438806093945941831432623367272568173893997325464109264
DP = -57260184070162652127728137041376572684067529466727954512100856352006444159428
DQ = -56270397953566513533764063103154348713259844205844432469862161942601135050224
InverseQ = -5297700950752995201824767053303055736360972826004414985336436365496709603273
D = 5967761894604968266284398550464653556930604493620355473531132912985865955601309375321441883258487907574824598936524238049397825498463180877735939967118353

更新

答えによると、RSAParametersで正しく動作するように.NetBigIntegerクラスの小さな拡張メソッドを作成しました。

public static class BigIntegerExtension
{
    public static BigInteger FromBase64(this BigInteger i, string base64)
    {
        byte[] p = Convert.FromBase64String(base64).Reverse().ToArray();
        if (p[p.Length - 1] > 127)
        {
            Array.Resize(ref p, p.Length + 1);
            p[p.Length - 1] = 0;
        }
       return new BigInteger(p);
    }

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

使用例:

BigInteger modulus1 = new BigInteger().FromBase64("rcLI1XTfmXtX05zq67d1wujnUvevBu8dZ5Q5uBUi2mKndH1FZLYCKrjFaDTB/mXW1l5C74YycVLS6msY2NNJYw==");

BigInteger modulus2 = new BigInteger().FromBigEndian(param.Modulus);

これが同じ問題を抱えている他の人に役立つことを願っています:-)

4

2 に答える 2

10

これがあなたが提供したXMLパラメータの私の解析です:

N = 9100595563660672087698322262735024483609782000266155222822537546670463733453350686171384417480667378838400923087358115007100900745853538273602044437940579

P = 96731388413554317303099785843734797692955743043844132225634400270674214374921

Q = 94081101418218318334927154927633016498744568046568114230258529096538660255499

確認できるように、Nは確かにP*Qに等しくなります。

BigInteger(byte [])コンストラクターは、バイト配列がリトルエンディアンであると想定されているため、またMicrosoftが低調なことを行っているため、現在のように使用することはできません。代わりに、バイトの順序を逆にします。最後に、バイト配列は2の補数であると想定されており、数値は正であることが保証されているため、上位バイトが128以上になる場合は、配列の上位バイトにゼロバイトを追加する必要があります。 。

于 2012-12-28T18:07:02.293 に答える
6

BigInteger配列を符号付きリトルエンディアン値として解析します。RSAParameters符号なしビッグエンディアンを使用します。

だからi = new BigInteger(bytes.Reverse().Concat(new byte[]{0}).ToArray()))うまくいくはずです。

于 2012-12-28T18:12:01.423 に答える