顧客の完全なクレジットカードの詳細(番号、名前、有効期限、CVV2)を短期間保存することを強制するビジネス要件があります。
理論的根拠:顧客が製品を注文するために電話をかけ、その場でクレジットカードが拒否された場合、販売を失う可能性があります。あなたが彼らの詳細を取り、取引に感謝し、そしてカードが拒否されていることに気付いた場合、あなたは彼らに電話をかけ直すことができ、彼らは製品の別の支払い方法を見つける可能性が高くなります。クレジットカードが受け入れられた場合は、注文から詳細をクリアします。
これは変更できません。既存のシステムはクレジットカードの詳細をクリアテキストで保存しますが、これを置き換えるために構築している新しいシステムでは、明らかにnotこれを複製します!
それでは、私の質問は、どうすればクレジットカードを短期間安全に保管できるかということです。明らかに何らかの暗号化が必要ですが、これを行うための最良の方法は何ですか?
環境:C#、WinForms、SQL-Server。
基本的には、責任を持ってCCの詳細を保存することは絶対に避けてください。ただし、Paypal/Verisignなどのトランザクションを実行するためにサードパーティのサービスを使用していると想定できます。ほとんどの場合、CCを保存できるAPIがあります。資格情報は彼らの側にあり、後でトランザクションを完了または開始するために使用できるキーを返します。そのため、彼らは難しい部分を処理しますが、あなたがしなければならないのはこの文字列キーをDBに保存することだけです。
CVV情報を保存することは実際には違法ではないと思いますが(法律に違反しているという意味で)、ペイメントカード業界の規則に違反しており、さまざまな制裁を課す可能性があります。したがって、あなたの要件は実際にはあなたがクレジットカードを受け入れることができないという結果になる可能性があります;-(
アンドリュー、あなたは PCI-DSS を理解する必要があります。小さな仕事ではありません。個人的には非常に曖昧だと思いますが、これが私が理解していることです。
まず、あなたが説明したシナリオから、私はカードに全額を承認しようとします。それが失敗した場合は、誰かがユーザーに連絡できるように、顧客の情報(カード会員データではない)を保存します。私が仕事をしていたところ、カードが有効であることを確認するために、一部の顧客は$ 1.00しか請求せず、すぐに取引を無効にしました。その後、すべての注文を手動で処理します。
番号を保存する必要がある場所は、承認が成功した場合です。その場合、必要な番号はクレジットカード番号とトランザクションコードだけです(少なくとも、これまでに使用したすべてのゲートウェイで)。
前回私がそれを見たときの標準は、暗号化アルゴリズムに固有のものではありませんが、代わりに、現在解読不可能な暗号化であるべきであることを明確にしています。
さて、あなたができないことの1つは、認証後にCCVを保存することです。私の理解では、承認前にそれを保存することはできますが、それを書面で書く人を得ることができませんでした。基本的に、あなたはカードを承認します、あなたはそれを拭いたほうがいいです。
そして、この時点で違法ではありませんが、あなたが釘付けになると、彼らはあなたにハンマーを降ろします。彼らはあなたに対して重い罰金を科す権限の範囲内にありますが、彼らが通常行うことはあなたを是正することであるようです。あなたが従わない場合、私はこれが起こっているのを聞いた誰もが従ったので何が起こるかわかりません。しかし、それから彼らは本当に顕微鏡であなたの戦利品を上げます。
結局のところ、彼らが本当に持っている唯一のスティックは、あなたがクレジットカードを受け入れないようにすることだと思います。私が一緒に働いたほとんどの商人はまさにそれの死を恐れていました。
クレジットカード情報を保存する場合は、PCIに準拠している必要があります。そうでない場合は、問題が発生します。
そうは言っても、SQL Server2005以降で利用可能なセルレベルの暗号化を見てください。偶然にも:)最近、SQL Server 2005/2008を使用した暗号化に関するT-SQLサンプルのプレゼンテーションを行いました: http://moss.bennettadelson.com/Lists/Events/Attachments/9/June2008.Zip (リンクの場所は2008年12月23日に更新されました)
文字列をメモリに短期間保存したいだけの場合は、 System.Security.SecureString を参照してください。
これから取られた 答え :
SecureString値は暗号化されて(難読化されて)保存されますが、最も重要なことは、ディスクにスワップされることはなく、使い終わったらすぐに破棄できることです。
一度に1文字しか作成できないため(ユーザーがパスワードを入力するときにキーストロークをキャプチャして作成することをお勧めするため)、使用するのは難しいです。また、回復してプレーンテキストを消去するには、3行のコードが必要です。ただし、適切に使用すると、仮想メモリの脆弱性を回避することで、プログラムをより安全にすることができます。
例の最後で、SecureStringは通常の管理対象文字列に変換されるため、再び脆弱になります(終了したら、try-catch-finallyパターンを使用して文字列をゼロにします)。 SecureStringの用途は、ガベージコレクターが値に対して作成するコピーの数を制限し、スワップファイルに書き込まれる可能性を減らすことにより、攻撃の表面積を減らすことです。
// Make a SecureString
SecureString sPassphrase = new SecureString();
Console.WriteLine("Please enter your passphrase");
ConsoleKeyInfo input = Console.ReadKey(true);
while (input.Key != ConsoleKey.Enter)
{
sPassphrase.AppendChar(input.KeyChar);
Console.Write('*');
input = Console.ReadKey(true);
}
sPassphrase.MakeReadOnly();
// Recover plaintext from a SecureString
// Marshal is in the System.Runtime.InteropServices namespace
try {
IntPtr ptrPassphrase = Marshal.SecureStringToBSTR(sPassphrase);
string uPassphrase = Marshal.PtrToStringUni(ptrPassphrase);
// ... use the string ...
}
catch {
// error handling
}
finally {
Marshal.ZeroFreeBSTR(ptrPassphrase);
}
適切に準拠し、そのようなことを実行できるようになるには、約30,000ドルの費用がかかります。サードパーティの支払いサービスを使用することをお勧めします。個人的には、Element Expressをお勧めします。これらには、PCI-DSSPAPDBコンプライアンスをバイパスする「ホスト型」ソリューションがあります。 POSマシンでさえ、自分のアプリケーション用にこれに変換する必要がありました!!!それは大きな苦痛ですが、私たちは小さな会社です。
上記のリンクには、準拠するためのコストに関するいくつかの良い情報があります。クレジットカード番号の保管をお願いするお客様もいらっしゃいますが、罰金が科せられる可能性もありますので、保管いたしません。良くない。責任を問わないでください。
編集:
さらに、クレジットカード情報を保存することにした場合は、使用する暗号化の形式を必ず検討する必要があります。対称?非対称?
対称暗号化(パスキー)を実行すると、キー(暗号化が必要)を持つサーバー(サイト)が何らかの形で侵害された場合に、深刻なセキュリティの脆弱性が発生する可能性があります。コンパイルされたコードでさえテキストキーを隠さないことを忘れないでください。
非対称暗号化(公開/秘密鍵ペア)を使用する場合、いくつかの追加の問題が発生しますが、プライマリ公開サーバーが侵害された場合、公開鍵しかありません。彼らはまたあなたのデータベースにアクセスします..彼らは内容を解読することができません。
問題は、秘密鍵をどこに保存するかということです。管理機能を実行しているときに、誰かがローカルコンピュータから貼り付けていますか。デスクトップ上で実行され、注文などを表示する別のアプリケーションがあります。
考慮すべきことがたくさんあります。
最後の注意:支払いゲートウェイ(Element Express、Authorize.NET、Paypalなど)を使用し、クレジットカード情報をローカルに保存しないでください。 :P
C#でのX509非対称暗号化の使用に関するリンクは次のとおりです。 http://www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html
可能であれば、データの保存を避けるべきであることに同意しました。しかし、多分あなたはその第三者ですか?もしそうなら、 PCI基準 に精通してください。サイトを少し見てみると、実装するのに必要なセキュリティ対策が見つかります。
要件を少し違った方法で見てみましょう。現在、次のようになっています。
WebサイトXの製品所有者として、CC会社によって拒否された販売を回復できるように、システムに顧客のccの詳細を一時的に保存してもらいたい
Pplはそのように考え、そのように機能を要求する傾向があります。今、私はあなたの要件が次のようにより便利に説明されていると思います:
ユーザーとして、ウェブサイトXで購入の支払いを再試行できるようにしたいので、チェックアウトプロセスを再度実行する必要はありません。これは、本当に苦痛です...
それで、(あなたの側に)何かを保存するための明示的な要件はありませんか?その唯一の暗示
支払いプロバイダーは、マーチャントアカウントにプログラマティックAPIを提供し、拒否された試行に対して再認証を試行する機能を提供できます。 @bashmohandesは以前にこれを回避したと思います
すべての決済プロバイダーがこれを実行できるわけではありませんが、関係する銀行との関係に依存していると思います。それはあなたが避けたいものです。銀行と緊密な関係を持っています。
シナリオ1:私が言ったことすべてが真実であると仮定する
承認試行への参照以外は何も保存する必要はありません。一部の決済プロバイダーは、優れたバックオフィスツールを提供しているため、再認証を行うために独自のツールを作成する必要はありません。ペイゲートがこれを行うと思います
私が信じるあなたの最善の策は、多くの支払いプロバイダーにインタビューすることです。彼らは手の甲のようにこのことを知っているべきです。これは潜在的にゼロコードソリューションです
シナリオ2:私が完全に間違っていると仮定しますが、合法的にこのCCのものの保存は問題ありません
したがって、そのデータを一時的にどこかに保存する必要があります。私はアドバイスします:
シナリオ2で私が提案したのはハードルだけですが、最終的には永続性がデータに到達するための競争に勝ちます。データを完全に保護する唯一の方法は、サーバーをエーテルから切断することですが、そのオプションは少し過激です:-)
シナリオ1は素晴らしいでしょう。じゃないですか。
tログを検討してください!
顧客に完全な影響(およびコンプライアンスに違反していることが判明した場合の是正要件)を説明し、私を信頼すると、「ビジネス要件」は非常に迅速に変化します。
クレジットカード番号を保存する必要があり(そして、ここでは合理的なシナリオがないという考えを進めます)、データベースに組み込まれているネイティブ暗号化を使用する場合は、次のことを考慮してください。トランザクションログはどうですか?
トランザクションログにクレジットカード番号が平文で反映されている可能性がある場合は、コンプライアンス違反であり、問題が発生した場合は、サイトで10,000ドルから50,000ドルの法廷監査の予算を立てる必要があります。あなたがこれらすべてのことを知っているべきだったのであなたの顧客があなたを訴える場合に備えてあなた自身の弁護士のための予算。
したがって、クレジットカード番号を保存する場合は、暗号をコードで実行して、トランザクションログ(挿入または更新)がカード番号ではなく暗号化された文字列を反映するようにします。
また、データベースにCVVのフィールドまたは列(暗号化されているかどうかに関係なく)がない場合、フォレンジック監査によってこれが明らかになり(ログも明らかになります)、顧客は大きな問題に直面します。彼らは罰金を支払い、クレジットカードを受け入れる能力を失う可能性があります。あなたの弁護士はとても幸せになります。
機密データをデータベースに保存するというこの正確な状況を扱ったブログ投稿があります。ブログ投稿では、Triple DESアルゴリズムを使用して構築したStringEncryptorクラスを使用していますが、必要に応じて独自のクラスをプラグインできます。
ブログ投稿には、使用されたビデオとソースコードが含まれています。 http://www.wrightin.gs/2008/11/how-to-encryptdecrypt-sensitive-column-contents-in-nhibernateactive-record-video.html で確認できます。それは間違いなくあなたの問題を解決すると思います。