3

ECDSA と secp256r1 曲線 (P256) およびメッセージ ハッシュの SHA256 アルゴリズムを使用して署名を生成しようとしています。また、Bouncy Castle ライブラリを使用しています。以下のコード、

public class MyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new MyTest().getSign();
    }

    void getSign() {
        // Get the instance of the Key Generator with "EC" algorithm

        try {
            KeyPairGenerator g = KeyPairGenerator.getInstance("EC");
            ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
            g.initialize(kpgparams);

            KeyPair pair = g.generateKeyPair();
            // Instance of signature class with SHA256withECDSA algorithm
            Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
            ecdsaSign.initSign(pair.getPrivate());

            System.out.println("Private Keys is::" + pair.getPrivate());
            System.out.println("Public Keys is::" + pair.getPublic());

            String msg = "text ecdsa with sha256";//getSHA256(msg)
            ecdsaSign.update((msg + pair.getPrivate().toString())
                    .getBytes("UTF-8"));

            byte[] signature = ecdsaSign.sign();
            System.out.println("Signature is::"
                    + new BigInteger(1, signature).toString(16));

            // Validation
            ecdsaSign.initVerify(pair.getPublic());
            ecdsaSign.update(signature);
            if (ecdsaSign.verify(signature))
                System.out.println("valid");
            else
                System.out.println("invalid!!!!");

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

}

ここでは、キー ペアは KeyPair を使用して生成されますが、私の要件では、静的な privateKey と公開キーを使用します。また、署名の検証は常に false を返します。

ヘルプが必要です。静的な秘密鍵と検証部分を取得するにはどうすればよいですか。

4

2 に答える 2

8

ジャックポット - タイトルに問題はありません!

まず、実際に BouncyCastle を使用していない可能性があります。Sun/Oracle Java 7 および 8 には EC プロバイダーが含まれるようになり (以前のバージョンには含まれていませんでした)、引数が 1 つの形式のgetInstanceは、最初に利用可能なプロバイダーを使用します。これは、ユーザーまたは誰かがプロバイダー リストを変更していない限り、通常は SunEC です。

署名を検証するには:署名に渡したのと同じデータを検証に渡します。バイトごとにまったく同じです。にのみ署名値を渡します。データを入れるのはばかげています。この値は実行中の Java プロセスに固有のものであるため、受信プロセスに送信する必要があります (異なる場合は、通常どおり)。Signature.update()Signature.update()Signature.verify()PrivateKey.toString()

静的キーを使用するには:まさにそれを行います。キーペアを作成してどこかに保存し、読み込んで使用します。最も安全な (パスワードで保護された) ストアは Java KeyStore (JKS) ファイルですが、これには証明書チェーン (おそらくダミーのもの) が必要で、自分でコーディングするのは面倒です。幸いなことに、keytoolユーティリティ-genkeypairはダミーの自己署名証明書を-keyalg ec -keysize 256使用してキーペアを生成し、(非常に人気のある) secp256r1 曲線を使用します。また、任意の 、ダミー証明書に付ける任意の名前、およびパスワードも指定し-alias nameます。-keystore filenameJKS ファイルのキーペアを使用するには:

  • を使用java.security.KeyStore.getInstance("JKS")してストア オブジェクトを作成し、ファイルとパスワードを渡し.load(InputStream,char[])ますFileInputStream

  • PrivateKey を取得するには、使用.getKey(String alias,char[] password)してキャストします。署名に使用します。

  • .getCertificateChain(String alias)[0].getPublicKey()最初の (唯一の) 証明書から PublicKey を取得するために使用します。検証に使用します。

于 2014-08-12T11:44:13.837 に答える
0

将来の読者のために、最初の質問のコードを最終的な作業バージョンで更新することにしました。

    try {
        KeyPairGenerator kg = KeyPairGenerator.getInstance("EC");
        ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
        kg.initialize(kpgparams);

        KeyPair kp = kg.generateKeyPair();
        PublicKey pubKey = kp.getPublic();
        PrivateKey pvtKey = kp.getPrivate();

        // sign
        Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
        ecdsaSign.initSign(pvtKey);
        String message = "text ecdsa with sha256";//getSHA256(msg)
        ecdsaSign.update(message.getBytes(StandardCharsets.UTF_8), 0, message.length());
        byte[] signature = ecdsaSign.sign();

        // Validation
        ecdsaSign.initVerify(pubKey);
        ecdsaSign.update(message.getBytes(StandardCharsets.UTF_8), 0, message.length());
        boolean result = ecdsaSign.verify(signature);

        assertTrue(result); // junit5 assert
    } catch (Exception e) {
         e.printStackTrace();
    }
于 2021-07-08T07:16:06.990 に答える