ログイン URL の一部に認証を含める必要があるサーバーを使用しています。このスキームが機能する方法(マニュアルで推奨されているように)は、
- 公開鍵と秘密鍵のペアは、Java JDK keytool (Java キーストアに作成されます) を使用して生成されます。
- Java JDK keytool を使用してキー ペアの証明書が生成されます。
- 証明書がサーバーにインストールされます。
クライアントにログオンするとき(私のコード)
- 平文のトークン文字列を生成します
- SHA1 と DSA を使用して、秘密鍵で平文のトークン文字列に署名します
- ログイン URL に署名付きトークン文字列が含まれます。
Java keytool はキーストアから秘密鍵をエクスポートするメカニズムを提供しませんが、個別にキーストアから秘密鍵を抽出してファイルに保存する Java コードがあります - How do I list / export private keys from aキーストア? .
これはすべて、クライアントが Java を使用して署名を行う場合に機能します。次のようなコードを使用します。
String plaintext = "This is a sample plaintext token string";
Signature instance = Signature.getInstance("SHA1withDSA");
instance.initSign(privateKey);
instance.update((plaintext).getBytes());
byte[] signature = instance.sign();
次のようなコードを使用して、クライアントが PHP を使用して署名を行う場合にも機能します。ここで、秘密鍵は PHP の Java キーストア ファイルから取得されます。]
$privateKey = openssl_pkey_get_private("file://$keyfile", $keystorePassword);
openssl_sign($paramsEncoded, $signature, $privateKey, OPENSSL_ALGO_DSS1))
しかし、顧客が Bash スクリプトと openssl を使用してログイン URL を作成したいという状況が発生しましたが、それは機能しません。そのコードの最新バージョンは次のようになります。これは、SHA1 メッセージ ダイジェストと DSA 署名を行います。しかし、サーバーはトークンを拒否します。
echo $tokenString | openssl dgst -sha1 > tokendigest
openssl dgst -dss1 -passin pass:$storePassword -sign $privateKeyFile > tokensigned
この投稿 ( Using SHA1 and RSA with java.security.Signature vs. MessageDigest and Cipher ) に出会いました。これは、Java 署名署名メソッドがダイジェストに署名するのではなく、ダイジェスト アルゴリズム ID とダイジェストの連結に署名することを示唆しています。 . 投稿のコードをステップ実行した後、(SHA1 の場合) ダイジェストの前に bytes を付ける必要があるよう48 33 48 9 6 5 43 14 3 2 26 5 0 4 20
です。しかし、それを追加した後でも、サーバーが受け入れられる署名付きトークンをopensllに生成させることはできません。
openssl を使用して Java 署名署名方式をエミュレートする方法を知っている人はいますか?