Tink では、個々の鍵の代わりに鍵セット(keyset)を、アルゴリズムの代わりに ECDSA_P256 や ED25519 などの名前付きテンプレートを使います。鍵セットは ID 付きの鍵の集まりで、そのうち 1 つがプライマリに指定されています。プリミティブ(PublicKeySign、PublicKeyVerify)は鍵のローテーションを透過的に行います。これがこの設計の狙いであり、相互運用で思わぬ問題が起きる原因でもあります。鍵セットは PEM ではなく、Tink JSON またはバイナリの protobuf として保存されます。
デフォルトの ECDSA_P256 テンプレートは、出力プレフィックス(0x01 と 4 バイトの鍵 ID)を先頭に付け、その後に DER 署名を続けます。JDK はこのような署名を Invalid encoding for signature で拒否しました。Tink 以外の検証者はどれも同じように拒否します。名前が _WITHOUT_PREFIX または _RAW で終わるテンプレートはプレフィックスを付けませんが、名前からはエンコーディングもわかりません。ECDSA_P256_RAW が出力したのは DER ではなく、64 バイトの IEEE P1363 形式の r‖s でした。この署名は JDK の SHA256withECDSAinP1363Format では検証を通り、SHA256withECDSA では失敗しました。サンプルが ECDSA_P256_IEEE_P1363_WITHOUT_PREFIX を使っているように、相手側が想定するエンコーディングに正確に合わせてテンプレートを選び、DER ⇄ 生形式の変換ツールでバイト列を確認してください。
外部の公開鍵は SignaturePemKeysetReader を通してインポートしますが、こうして得た鍵で検証できたのは DER 署名だけでした。Tink で生成した P1363 形式の鍵が受け入れた生形式の署名も、PEM からインポートした鍵では、DER に再エンコードするまで検証に失敗しました。署名にはランダムな nonce が使われ、s は正規化されず、検証では high-S も受け入れられます。不正な入力に対しては GeneralSecurityException: invalid signature がスローされます。
Tink for Java 1.24.0 には、P-256、P-384、P-521 の ECDSA、Ed25519、RSA(PKCS#1 v1.5 と PSS)のテンプレートがあります。このリリースには ML-DSA や SLH-DSA のテンプレートは登録されていません(Name ML_DSA_65 does not exist)。現時点で JVM 上でポスト量子署名を使うには、Java JCA か Bouncy Castle を参照してください。