9

ユーザーが購入を完了したときに取得できるように、現在クレジット カード データをセッションに保存しているショッピング カートのチェックアウト プロセスがあります。購入プロセスは、ユーザーがクレジット カードを入力し、確認ページを表示して、注文を確定するように設定されています。クレジット カード データへのアクセスが必要なアクションは、確認アクションとファイナライズ アクションの 2 つだけであり、安全を確保するために他のすべてのアクションはデータを破棄する必要があります。

ベースコントローラーでリフレクションを実行して、ユーザーが呼び出している現在のアクションを確認する以外に、許可されていないリクエストのデータを破棄するエレガントな方法を思いつきません。さらに、ユーザーがデータを入力した後に別のリクエストを行わなかった場合、ユーザーがウェブサイトに戻ってくるまでセッションに残ります。私が提供された 1 つの提案は、データを非表示フィールドに暗号化し、SSL チケットに依存してマークアップのキャッシュを防ぐことでした。これはかなり安全なアプローチのように思えますが、クレジット カード データをユーザーがアクセスできる場所に暗号化して配置するかどうかにかかわらず、私はあまり好きではありません。クライアントがクレジット カード データの保存を望まないため、データベースへの保存は無効です。

クレジット カード情報などの機密データを複数のページ リクエストにわたって一時的に永続化するための理想的な方法は何ですか?


これが十分なアプローチであるかどうか、誰かが教えてくれるかもしれません。オブジェクトが新しくなるたびに生成される一意の Guid を持つようにセッションに保存されているショッピング カートを設定しました。その Guid は、Rijndael アルゴリズムでシリアル化しているクレジット カード データを暗号化および復号化するためのキーとして使用されます。暗号化されたカード データは非表示フィールドでユーザーに渡され、[ファイナライズ] をクリックするとデシリアライズされます。最終結果は、次のような文字列になります。

VREZ%2bWRPsfxhNuOMVUBnWpE%2f0AaX4hPgppO4hHpCvvwt%2fMQu0hxqA%2fCJO%2faOEi%2bX3n9%2fP923mVestb7r8%2bjkSVZDVccd2AJzCr6ak7bbZg8%3d

public static string EncryptQueryString(object queryString, Guid encryptionKey)
{
    try
    {
        byte[] key = Encoding.UTF8.GetBytes(ShortGuid.Encode(encryptionKey).Truncate(16));//must be 16 chars
        var rijndael = new RijndaelManaged
                           {
                               BlockSize = 128,
                               IV = key,
                               KeySize = 128,
                               Key = key
                           };

        ICryptoTransform transform = rijndael.CreateEncryptor();

        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(queryString.ToString());

                cs.Write(buffer, 0, buffer.Length);
                cs.FlushFinalBlock();
                cs.Close();
            }
            ms.Close();
            return HttpUtility.UrlEncode(Convert.ToBase64String(ms.ToArray()));
        }
    }
    catch
    {
        return null;
    }
}
4

3 に答える 3

11

このシナリオを処理する最善の方法は、次の 2 つのことをサポートする支払いサービスを使用することです。

  1. 承認 -> 完了セマンティクス。
  2. トークン化

オーソリにより、支払い情報を受け取った時点で指定された請求額を予約できます。完了により、支払い/注文が確認されたら、請求を支払いバッチにコミットできます。注文がキャンセルされた場合、Completion を発行する必要はなく、オーソリの削除を試みることもできます。

トークン化に関して、前述の支払い処理方法をサポートするほとんどのゲートウェイは、保留中のトランザクションに対してトークン (通常は数値 ID) を返します。トークンは、ゲートウェイで認証資格情報にアクセスできない人にとっては価値がないため、必要に応じて処理できます。これにより、安全の負担もゲートウェイに移されます。

料金をゲートウェイ/プロセッサに中継する以外の方法で実際のクレジット カード情報を保存することは、お勧めできません。データを保護するという問題を超えて、これにより、アプリケーションは PCI/PABP のカード情報ストレージ スコープに入ります。これには、アプリケーションで処理したくない多くの規則や規制が伴います。また、規制に準拠したアプリケーションに対して来年課される規制料金もあると思います。これらすべては、あなたやあなたのクライアントにとって、面倒なことに値するものではありません。

最後に、中間処理 (ページ内/イベント/ルート ハンドラー) 中に、SecureString を使用して、データが不要になるまでデータの内容を保持できます。

SecureString クラス (System.Security) @ MSDN

于 2009-12-22T17:15:47.643 に答える
2

TempData の使用についてはどうですか? 確認アクションとファイナライズ アクションの間に値を TempData に戻す必要がありますが、少なくとも要求ごとに破棄されます。TempData は保存にセッションを使用するため、保存中は安全ではありませんが、自動削除機能があることに注意してください。私も、ページに番号を保存することに抵抗します。これは PCI 規則に違反していると思われます。

もう 1 つの方法は、カード情報をデータベースに保存することです。アプリケーションでそれを保持している場合は、おそらくすでに PCI ルールの対象になっていることになります。DB に保存すると、後続のリクエストに請求カード ID を入力するだけで済むため、簡単になります。これは簡単に隠しフィールドにある可能性があります。

于 2009-12-22T17:06:49.600 に答える
0

これはどの国に基づいており、どのクレジットカード会社が関与していますか? 実際に完全なクレジット カード番号を (どんな形式であれ) クライアントに送り返すという全体的なアプローチは、プロのクレジット カード処理を扱っていないかのように聞こえます (それを侮辱と見なさないでください)。

クライアントは、Visa/MasterCard/AMC/Discover のオンライン クレジット カード処理 (PCI DSS) に関する集合規則に違反することをいといませんか? あなたのクライアントは、主要なクレジットカード会社から彼らとの取引を禁止される可能性があります. 一般に、独自のオンライン クレジット カード処理ソリューションを展開しようとするのは非常に悪い考えです。クライアントに深刻な罰金が適用される可能性があるため、独自の暗号化アルゴリズムを展開するよりも悪い考えです (加盟店契約の細則)。真の PCI DSS ソリューションでは、認証と監査に数万ドルを費やして、クレジット カード データを真に安全な方法で処理する必要があります。これが、ほとんどの人が既存のオンライン プロセッサを使用している理由です。

于 2009-12-22T17:16:28.437 に答える