6

次のように AsymmetricCipherKeyPair を生成します。

string curveName = "P-521";
X9ECParameters ecP = NistNamedCurves.GetByName(curveName);
ECDomainParameters ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDH");
g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
AsymmetricCipherKeyPair aKeyPair = g.GenerateKeyPair();

私の意図は、公開鍵と秘密鍵を抽出し、後で鍵を再構築することでした。最初に次のようにキーを抽出しました。

byte[] privateKey = ((ECPrivateKeyParameters)aKeyPair.Private).D.ToByteArray();
byte[] publicKey = ((ECPublicKeyParameters)aKeyPair.Public).Q.GetEncoded();

公開鍵パラメーターと秘密鍵パラメーターを使用できるように再作成するにはどうすればよいですか? この例では、秘密鍵を再作成してから、データ バイト配列に署名します。

public static byte[] SignData(byte[] data, byte[] privateKey)
{
    string curveName = "P-521";
    X9ECParameters ecP = NistNamedCurves.GetByName(curveName);
    ECDomainParameters ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
    ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
    BigInteger biPrivateKey = new BigInteger(privateKey);
    ECPrivateKeyParameters keyParameters = new ECPrivateKeyParameters(biPrivateKey, ecSpec);
    signer.Init(true, keyParameters);
    signer.BlockUpdate(data, 0, data.Length);
    return signer.GenerateSignature();
}

本物のハックのように感じますが、うまく機能します。公開鍵でこれを行うにはどうすればよいですか? 変数 xxx を (ECPublicKeyParameters)aKeyPair.Public に設定すると、以下のコードを使用して署名を検証できます。xxx を直接使用することもできますが、ポイントは xxx をシリアル化してから戻すことです。そのため、このコードは実際に xxx 変数を変換し、xx に格納される新しい変数を作成します。次に、xx を使用して検証します (これは、キーを往復できることを示しています)。

var xx = PublicKeyFactory.CreateKey(Org.BouncyCastle.X509.SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(xxx).GetDerEncoded());
ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
signer.Init(false, xx);
signer.BlockUpdate(data, 0, data.Length);
return signer.VerifySignature(signature);

秘密鍵の場合と同じように、Q.GetEncoded() からキー (xx) を作成できることを期待していました。

秘密鍵を再構築するより良い方法はありますか? ASN.1エンコーディングも使用していますか? もしそうなら、おそらく私は代わりにそれを使うべきです。

4

1 に答える 1

5

私は次のようにこれを行うことができます:

string curveName = "P-521";
X9ECParameters ecP = NistNamedCurves.GetByName(curveName);
FpCurve c = (FpCurve)ecP.Curve;
ECFieldElement x = new FpFieldElement(c.Q, xxx.Q.X.ToBigInteger());
ECFieldElement y = new FpFieldElement(c.Q, xxx.Q.Y.ToBigInteger());
ECPoint q = new FpPoint(c, x, y);
ECPublicKeyParameters xxpk = new ECPublicKeyParameters("ECDH", q, SecObjectIdentifiers.SecP521r1);

次に、xxpk を使用して署名を検証します。

免責事項:これがこれを行うための最良の方法であるとは主張しません。機能するというだけです!

于 2013-07-03T12:43:48.647 に答える