2

指定された文字列形式の確認コード$vk_macを含むクエリを銀行に送信する必要があります。コードは、公開鍵で暗号化され、base64形式で表示されるSHA1ハッシュとRSAである必要があります。残念ながら、これまでのところ、私は失敗しています-銀行は私に「間違った署名」を与え、私が得ているすべての情報を教えてくれます。

私が持っているのはこれです:

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents("private_key.pem"));
$rsa->loadKey($rsa->getPublicKey());
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$encrypted = $rsa->encrypt(sha1($vk_mac));
$vk_mac = base64_encode($encrypted);

ここでのprivate_key.pemは、プレーンテキストの秘密鍵です。暗号化モードをCRYPT_RSA_ENCRYPTION_OAEPに設定してみましたが運が悪かったです。開始$vk_mac文字列が正しくフォーマットされ、必要なすべての詳細が含まれていることを99.9%確信しています。

誰かが私が間違っていることを知っていますか?ありがとうございました。


編集:

コードを次のように変更しました(vk_macは署名が必要な開始形式の文字列で、private_key.pemはデコードされた秘密鍵です)。

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents("private_key.pem"));
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$hashed = $rsa->hash->hash($vk_mac);
$encrypted = $rsa->sign($hashed);
$signature = base64_encode($encrypted);

これを行うと、生成された署名が正しいことがわかります。

$rsa->loadKey($rsa->getPublicKey());
$verified = $rsa->verify($hashed, base64_decode($signature));

$verifiedはTRUEを返します。

ただし、銀行は「署名が正しくありません」と応答します。他にアイデアはありますか?

編集:

仕様

VK_MAC制御コードの計算

VK_MAC、電子署名用、リクエストで使用、使用されているアルゴリズムのバージョンをチェックおよび確認するため、パラメーターVK_VERSIONで示されます。今回はバージョン008を使用します。VK_MACは、BASE64コーディングの要求パラメーターとして表示されます。

バージョン008

MAC008関数の値は、公開鍵アルゴリズムRSAを使用して計算されます。空のフィールドの値も考慮されます–「000」。

MAC008(x1、x2、…、xn):= RSA(SHA-1(p(x1)|| x1 || p(x2)|| x2||…||p(xn)|| xn)、d、 n)

場所:|| は文字列x1、x2、…を追加する操作です。xnはクエリパラメータです。pはパラメータの長さの関数です。長さは3桁の文字列形式の数値です。dはRSAシークレット指数です。nはRSAモジュラスです。署名はPKCS1標準(RFC 2437)に従って計算されます。

4

3 に答える 3

3

$ rsa-> sign()を試してみたらどうなりますか?PKCS#1は、ハッシュを暗号化するだけでは署名を行いません。銀行が相互運用可能なRSAソリューションを使用している場合は、おそらくそれも行っていません。

于 2011-05-21T10:22:17.153 に答える
2

コードはほぼ正しかったですが、再度ハッシュする必要はありませんでした(@Accipitridaeに感謝します)。

解決策は、販売者のIDは大文字である必要があり、提供されているように小文字ではないということでした。仕様のどこにも大文字である必要があるとは書かれていません。良い。

于 2011-05-23T11:36:19.477 に答える
0

上記のように、opensslを使用するとこれを簡単に行うことができます。以下は私がそうする方法です。

$hashed = sha1($vk_mac);
openssl_public_encrypt($vk_mac, $encrypted, ($pubkey));
$vk_mac = base6$_encode($encrypted);

詳細については、openssl_public_encryptのドキュメントをお読みください。

于 2011-05-20T23:43:23.750 に答える