9

ドキュメントに署名してネットワーク経由でアプリケーションサーバーに送信する分散デジタル署名を開発しています。Javaでソケットプログラミングを使用しています。公開鍵はエンコードまたは圧縮する必要があると思います。つまり、x値とy値は、何らかの形で単一のバイナリデータとして表され、公開レジストリまたはネットワークに保存されますが、Javaでそれを行う方法がわかりません。

        // I have class like this 
           public class CryptoSystem{                  

               EllipticCurve ec = new EllipticCurve(new P192());

               //-------------------
               //--------------------

               public ECKeyPair generatekeyPair()
               {
                  return ECKeyPair(ec);

               }


            }    
        // i don't think i have problem in the above


    CryptoSystem crypto = new CryptoSystem();
    ECKeyPair keyPair = crypto.generateKeyPair();
    BigInteger prvKey = keyPair.getPrivateKey();
    ECPoint pubKey = keyPair.getPublicKey();
     // recommend me here to  compress and send it  the public key to a shared network.

公開鍵とドメインパラメータをエンコードする方法を知りたいので、署名の検証者はそれを使用するためにそれをデコードします。なぜなら、それらをネットワーク経由で検証者に送信するときは、をシングルバイト配列としてエンコードする必要があるからです。 .iはBouncyCastleProviderを使用していません。ECDSAアルゴリズムの実装全体が私のプロジェクトです

4

2 に答える 2

11

楕円曲線のポイントは、ほとんどの場合、X9.62 で指定されたエンコーディングを使用してエンコードされます。

ポイント圧縮の使用はオプションです。ポイント圧縮を使用してエンコードするのは簡単ですが、圧縮されたポイントをデコードするにはもう少し作業が必要なので、余分なバイトを本当に節約する必要がない限り、気にしません。必要な場合はお知らせください。詳細を追加します。X9.62 でエンコードされたポイントは、最初のバイト (0x02 または 0x03) によるポイント圧縮で認識できます。

ポイント圧縮を使用しないエンコードは非常に簡単です。0x04 から始めます (圧縮なしを示すため)。次に、最初に x 座標、次に y 座標を続けます。両方とも、フィールドのサイズ (バイト単位) まで左側にゼロが埋め込まれます。

int qLength = (q.bitLength()+7)/8;
byte[] xArr = toUnsignedByteArray(x);
byte[] yArr = toUnsignedByteArray(y);
byte[] res = new byte[1+2*qLength];
res[0] = 0x04;
System.arraycopy(xArr, 0, res, qLength - xArr.length, xArr.length);
System.arraycopy(yArr, 0, res, 2* qLength - yArr.length, nLength);

もちろん、これをデコードするのは簡単です。

于 2012-06-07T20:53:12.770 に答える
4

BC 実装が X9.63 エンコーディングを使用していることは確かなので、これらは標準化されたエンコーディングになります。Bouncy Castle プロバイダーを JRE に追加する必要があります (Security.addProvider(new BouncyCastleProvider())は、bouncy のドキュメントを参照してください。

public static void showECKeyEncodings() {

    try {
        KeyPairGenerator kp = KeyPairGenerator.getInstance("ECDSA");
        ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable
                .getParameterSpec("prime192v1");
        kp.initialize(ecSpec);
        KeyPair keyPair = kp.generateKeyPair();

        PrivateKey privKey = keyPair.getPrivate();
        byte[] encodedPrivKey = privKey.getEncoded();
        System.out.println(toHex(encodedPrivKey));

        PublicKey pubKey = keyPair.getPublic();
        byte[] encodedPubKey = pubKey.getEncoded();
        System.out.println(toHex(encodedPubKey));

        KeyFactory kf = KeyFactory.getInstance("ECDSA");
        PublicKey pubKey2 = kf.generatePublic(new X509EncodedKeySpec(encodedPubKey));
        if (Arrays.equals(pubKey2.getEncoded(), encodedPubKey)) {
            System.out.println("That worked for the public key");
        }

        PrivateKey privKey2 = kf.generatePrivate(new PKCS8EncodedKeySpec(encodedPrivKey));
        if (Arrays.equals(privKey2.getEncoded(), encodedPrivKey)) {
            System.out.println("That worked for the private key");
        }

    } catch (GeneralSecurityException e) {
        throw new IllegalStateException(e);
    }

}
于 2012-06-08T01:51:01.603 に答える