38 votes

Stocker des Numéros de Carte de Crédit en SESSION - des moyens autour d'elle?

Je suis bien conscient de la Conformité PCI, donc n'ont pas besoin d'une bonne dose sur le stockage des numéros de CC (et surtout CVV nums) au sein de notre entreprise de base de données lors du processus de commande.

Cependant, je veux être sûr que possible lors de la manipulation des consommateurs sensibles à l'information et je suis curieux de voir comment la contourner en passant CC les numéros de page en page SANS l'aide des variables de SESSION, si possible.

Mon site est construit de cette façon:

  1. Étape 1) recueillir de Carte de Crédit l'information de la clientèle - lorsque client hits soumettre, le l'information est d'abord exécuté par JS la validation, puis exécuter par le biais de PHP la validation, si toutes les passes qu'il se déplace à l'étape 2.
  2. Étape 2) l'Information est affichée sur une page de révision pour le client à faire assurez-vous que les détails de leur prochain des transactions sont affichés. Seul le les 6 premiers et les 4 derniers de la CC sont montré sur cette page, mais le type de la carte, et exp date sont shwon entièrement. Si il clique sur continuer,
  3. Étape 3) L'information est envoyée à une autre page php qui s'exécute une dernière validation, envoie des informations par le biais de la passerelle de paiement sécurisé, et la chaîne renvoyée est avec des détails.
  4. Étape 4) Si tout est bon et bien, le l'information des consommateurs (personnel, pas CC) est stocké dans la bd et la redirection pour une page de fin. Si quelque chose est mauvais, il est informé et a dit à revoir le CC et la page de traitement de essayez à nouveau (avec un maximum de 3 fois).

Toutes les suggestions?

MODIFIER

J'ai reçu beaucoup de très bonne réponse sur cette question à la majorité semblent être d'accord sur les points suivants:

  1. la prise de variables POST après l'exécution de la validation
  2. le chiffrement ccnum et le cryptogramme de sécurité (pas sûr vous êtes autorisé à stocker des cvv en DB à tous tout de même)
  3. Le stockage temporaire de la DB
  4. L'accès DB immédiatement après la "révision" la page est OK avais
  5. déchiffrer les détails de DB
  6. envoyer des informations de processeur
  7. recevoir de réponse
  8. résilier DB

Je pense que cela a un sens global. Quelqu'un at-il une bonne méthode pour le chiffrement/déchiffrement avec la meilleure façon de créer de la temp DB info qui est automatiquement supprimé au plus tard à l'appel?

Je suis à la programmation en PHP et MySQL DB

EDIT #2

Je suis tombé sur des Paquets Générale, ce qui semble être une solution idéale, mais VRAIMENT ne voulez pas payer pour une autre licence de logiciel pour atteindre cet objectif. http://www.packetgeneral.com/pcigeneralformysql.html

EDIT #3 - Exemple de Code

Maintenant j'ai posté un exemple de code que j'ai mis ensemble à essayer de faire sens de chiffrement/déchiffrement et de stockage mentionné dans ce post. J'espère que, déjà utile contributeurs peuvent valider et d'autres sont en mesure d'utiliser des fonctionnalités similaires. Pour des raisons de longueur, je ne vais pas entrer dans les méthodes de validation utilisée pour la CC num lui-même.

Formulaire De Saisie

<form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="text" name="CC" />
<input type="text" name="CVV" />
<input type="text" name="CardType" />
<input type="text" name="NameOnCard" />
<input type="submit" name="submit" value="submit" />
</form>

PHP Chiffrer et Stocker des Données

<?php

$ivs = mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($ivs,MCRYPT_RAND);
$key = "1234"; //not sure what best way to generate this is!
$_SESSION['key'] = $key;

$ccnum = $_POST['CC'];
$cvv = $_POST['CVV'];
$cctype = $_POST['CardType'];
$ccname = $_POST['NameOnCard'];

$enc_cc = mcrypt_encrypt(MCRYPT_DES, $key, $ccnum, MCRYPT_MODE_CBC, $iv);
$enc_cvv = mcrypt_encrypt(MCRYPT_DES, $key, $cvv, MCRYPT_MODE_CBC, $iv);
$enc_cctype = mcrypt_encrypt(MCRYPT_DES, $key, $cctype, MCRYPT_MODE_CBC, $iv);
$enc_ccname = mcrypt_encrypt(MCRYPT_DES, $key, $ccname, MCRYPT_MODE_CBC, $iv);


//if we want to change BIN info to HEXIDECIMAL
// bin2hex($enc_cc)

$conn = mysql_connect("localhost", "username", "password");
mysql_select_db("DBName",$conn);

$enc_cc = mysql_real_escape_string($enc_cc);
$enc_cvv = mysql_real_escape_string($enc_cvv);
$enc_cctype = mysql_real_escape_string($enc_cctype); 
$enc_ccname = mysql_real_escape_string($enc_ccname);

$sql = "INSERT INTO tablename VALUES ('$enc_cc', '$enc_cvv', '$enc_cctype', '$enc_ccname');

$result = mysql_query($sql, $conn) or die(mysql_error());
mysql_close($conn);

Header ("Location: review_page.php");

?>

PHP le décryptage des données et l'envoi de la passerelle

    $conn = mysql_connect("localhost", "username", "password");
    mysql_select_db("DBName",$conn);

$result = mysql_query("SELECT * FROM tablename");

echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_ccnum, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_cvv, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_cctype, MCRYPT_MODE_CBC, $iv);
echo mcrypt_decrypt (MCRYPT_DES, $_SESSION['key'], $enc_ccname, MCRYPT_MODE_CBC, $iv);

mysql_close($con);
?>

procéder ensuite à prendre les données qui viennent d'être envoyé dans la chaîne et de l'utilisation de la Passerelle de présentation. Semble juste?

13voto

Rex M Points 80372

Stocker les détails de la carte à tout persistance moyenne (base de données, peu importe), mais de crypter le numéro de carte unique et aléatoire de la clé que vous stockez dans la session. De cette façon, si la session est perdue, la clé est trop - ce qui vous donne suffisamment de temps pour nettoyer à fond expiré/abandonné de données.

Assurez-vous également que vos séances sont protégées contre le piratage. Il y a des solutions matérielles pour cela, mais un simple code de façon de faire est de prendre l'ID de session à un hachage du premier octet de l'adresse IP, plus l'agent de l'utilisateur. Pas infaillible, mais ça aide.

Edit: La clé de bits pour la réduction des risques est de s'assurer que vous vous débarrasser de cette info dès que possible. Juste après la transaction passe par, suppression de l'enregistrement de la base de données. Vous avez également besoin d'un rouleau d'emploi (tous les 5 minutes) qui supprime tous les enregistrements de plus de votre délai d'expiration de session (habituellement 20 minutes). Aussi, si vous utilisez une base de données pour cette très temporaire de données, assurez-vous qu'il n'est pas sur un système automatisé système de sauvegarde.

Encore une fois, cette solution n'est pas infaillible et je ne suis même pas sûr à 100%, il est compatible avec la CC exigences en matière de sécurité. Cependant, il devrait exiger un attaquant total d'exécution le contrôle de votre environnement activement décrypter client CC info, et si un instantané de votre base de données est compromise (beaucoup plus probable/commun), un seul CC peut être brute forcé à un moment, qui est sur le mieux que vous puissiez espérer.

9voto

Summer Points 1737

Envisager de modifier votre processus de commande, de se débarrasser de la nécessité de stocker des informations de carte de crédit.

Page 1: l'Utilisateur entre les non-cartes de crédit, les informations de commande, à l'instar de l'expédition et l'adresse de facturation
Page 2: l'Utilisateur vérifie non de la carte de crédit, les informations de commande, entre informations de carte de crédit, et clique sur "Payer Maintenant" (ou "Modifier l'Ordre" s'ils veulent changer les choses)
Étape 3: l'Info est transmis via un $_POST demande à un SSL page, ce qui achève de serverside contrôles, soumet des données de carte de crédit pour le processeur, et oriente l'utilisateur vers un succès ou d'erreur de la page en fonction de la réponse.

De cette façon, vous éviterez une brume de problèmes techniques et des problèmes de conformité. Le stockage de données de carte de crédit dans une base de données ou un cookie, même pour une courte période de temps, même si elle est cryptée, signifie que vous êtes responsable d'un niveau plus élevé de conformité à la norme PCI. La seule différence est que vous ne serez pas en mesure de montrer une "vérifier la commande" à la page avec les détails de carte de crédit. Et quelle grande différence est que, étant donné que votre "vérifier la commande" page peut même pas montrer l'intégralité de numéro de carte de crédit?

9voto

PaulG Points 7377

Je sais que vous avez mentionné que vous êtes conscient de la conformité PCI, mais en utilisant l'une des méthodes déjà décrites (par exemple, la persistance de la carte, le numéro de disque de n'importe où) va tomber sous le coup de PCI et de dire que vous avez un cauchemar de la conformité des maux de tête à l'avance de vous. Si vous avez vraiment insister sur la persistance de la carte numéro de disque, alors vous pourriez aussi bien obtenir un PCI maintenant pour vous aider à travers le processus et de vous offrir des conseils. Finalement, ils vont avoir besoin de valider la méthode que vous avez pris est approprié.

Comme un exemple, un grand nombre de réponses ici en parler à l'aide du chiffrement. C'est le plus difficile restait à faire. Ils n'ont pas parlé de gestion de clés qui est nettement plus difficile

Je pense donc qu'il serait préférable de soumettre les détails de la carte à la passerelle de paiement dès qu'elles sont collectées. Un bon nombre de passerelles de paiement vous permettra d'effectuer un magasin seulement le style de la transaction, qui sera la base de la validation des détails de carte et de stocker le numéro de la carte à leur (déjà conforme aux normes PCI) du serveur, et vous renvoie un id de jeton à la place. Cette méthode signifie que vous NE pas stocker le numéro de la carte/cvv2 n'importe où sur vos serveurs, et la conformité PCI devient une énorme quantité plus facile.

Plus tard dans le processus de commande, vous utilisez l'id de jeton de présenter une autorisation et de règlement.

PCI vous permet de stocker les six premiers/les quatre derniers chiffres (et date d'expiration) de la cardnumber en clair, de sorte que vous pouvez capturer en toute sécurité ceux où vous êtes à l'aise, de sorte qu'ils peuvent être réaffiché juste avant la dernière étape.

6voto

tc. Points 23958

Est-il une raison vous ne pouvez pas sauter l'étape de confirmation et il vous suffit de soumettre immédiatement la transaction?

Je ne vois pas pourquoi le garder dans une base de données est un plus sûr que de le garder dans une variable de session serveur compromis sera toujours donner le numéro de carte de crédit, mais si vous le gardez dans la session, il est beaucoup moins susceptibles d'être écrites sur le disque. Vous pouvez crypter si vous le souhaitez, mais l'utilité de ce qui est douteux (ça va encore être échangés sur le disque). L'ajout d'une autre machine pour faire de stockage crypté n'aide pas non plus, puisque la machine compromise pouvez simplement demander à l'autre de faire le décryptage.

EDIT: Viens de penser à ceci:

  1. Générer aléatoirement une clé de 128 bits. Sauver dans la session.
  2. Chiffrer les données avec la clé. L'envoyer au client dans un <input type="hidden">
  3. Lors de la confirmation, de déchiffrer les données et soumettre la transaction.

Un attaquant a besoin de compromettre à la fois le client et le serveur pour obtenir le numéro de carte de crédit (par exemple un attaquant aurait probablement le nombre déjà de toute façon). Un serveur en ligne compromis sera toujours obtenir les numéros de carte de crédit de transactions futures, mais vous ne pouvez pas vraiment un arrêt.

EDIT: Et j'ai oublié les détails. Pour l'ensemble de ces régimes (pas que le mien), vous avez également besoin d'un MAC pour prévenir les attaques de relecture (ou Eve distrait Alice, modifie le panier et l'adresse de facturation, puis cliquez sur "valider" de la page...). En général, vous voulez avoir un MAC sur toutes les données de transaction que vous avez (CC, le CRYPTOGRAMME de sécurité, ID de transaction, le montant de la transaction, adresse de facturation...).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: