クレカ番号入力アプリを作った。

無計画に買った磁気カードリーダー、高くは無いが3000円近くしたからこのままゴミにするのももったいない。何かに使えないか、考えてみた。

磁気カードリーダーMSR90 – アマゾン
https://amzn.to/3vIw8ib

昨日、ソニーストアで買い物をしたら、クレジットカードなどの情報を入れる画面で確認ボタンを押して次の画面に遷移してから入力に間違いがあると言われたり、自分で気づいて前の画面に戻ると、クレジットカードに関する情報が消えていてもう一度入れ直す必要があるというクソ仕様。5回くらい間違えて、そのたびにクレジットカード番号、期限、名義、セキュリティコードとなぜか誕生日を毎回入れ直す必要すハメに。

アイボのいちごミルクを買いたい(買いたくない)

ブラウザにはカード番号やCVC/CVV番号を保存する機能があるが、そんな気持ち悪い機能は使いたくないので毎回入力しているのだが、5回も入れ直しさせられると面倒になってくる。

そこで前回買ったカードリーダーを活用してクレジットカードを磁気カードリーダーに読ませるとウェブフォームに入力できるアプリを作ってみる。



※WordPress.comがケチでzipファイル直接置けないのでワード文書にOLEとして埋め込んだ。今どきのdocx自体がzipファイルなのに。→Windows Defenderが信頼されていない、と警告してくるのでソースだけ公開に変更。

使い方は簡単で、クレジットカード番号を入力する必要が出てきたらMagCard.exeアプリを起動してから、入力したい場所にカーソルを合わせる。もう一度MagCard.exeのウィンドウをアクティブにしてからカードをカードリーダーに読み込ませる。ウィンドウが消えてカード番号を入力する部分にキーストロークとして入力される。

起動すると微妙に怪しげな感じのウィンドウを表示する。
磁気カードをスワイプすると番号が入る。

こんな怪しげなソフトは自分以外の誰も使わないと思うけど、カード番号を読み込ませるとかいう極めてセキュアな用途に使用されるから、ソースコードはプロジェクトファイルも含めて全部アーカイブに入れてある。ソースにコメントを書いていないが初心者プログラマーでも読み解けるだろう。

動作としてカード番号自体はどこにも保存していないので、カード番号やパスワードを保存してまとめて管理できますなんてソフトなんかよりずっとセキュアじゃないかな※。ちなみにアメックスやダイナースのハイステータスなカードは持てないから試してない。(カードの桁数が異なるから、持ってないとうまく動くか試せない)

※個人的には、パスワード管理ツールって、最低限オープンソースかつデータストアに汎用なOneDriveかGoogleDriveを指定できるものでなければ、何やってるか分からないから絶対に使いたくない。それにオープンソースであっても動作を完全に掌握できるわけでもないし、コードやバイナリの安全性なんて個人で評価できるものでもない。安全って宣伝されたってそれを担保できる根拠が無ければクレジットカードの番号なんて怖くて預けられない。

これでUIがクソなECサイトでの買い物も楽になる。



取り出したMagCard.exeを実行するときにWindowsのSmart Screenが「信頼されていないファイル」として実行をブロックしてくれる。詳細情報で実行できるけど、嫌なら実行しなくてもいい。それにVisual StudioのソリューションファイルMagCard.slnを開くときも「信頼されていないソリューション」とか警告してくれるので、嫌なら開かなくてもいい。まあどこの馬の骨だか知らんやつが作ったファイルなんか迂闊に開いたり実行するなんてことは、情報リテラシーがある人ならしないのが基本だって知ってることだからSmart Screenの言ってることは正しい。

ということでバイナリ公開はやめてソースのみにする。よくある1個フォームのC#デスクトップアプリなんで特に説明も要らないかな。

MagCard.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MagCard
{
    public partial class MagCard : Form
    {
        int state;
        string keys; 

        public MagCard()
        {
            InitializeComponent();
            state = 0;
            keys = "";
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch(state)
            {
                case 0:
                    if(e.KeyChar == '%')
                    {
                        state = 1;
                    }
                    break;

                case 1: 
                    if(e.KeyChar == ';')
                    {
                        state = 2;
                        timer1.Interval = 500;
                        timer1.Start();
                    }
                    else
                    {
                        keys += e.KeyChar;
                    }
                    break;
            }    
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();
            state = 3;

            try
            {
                keys = keys.Substring(1, 16);
                this.Text = keys;

                this.Hide();
                SendStr(keys);
                this.Close();
                
            }
            catch(ArgumentOutOfRangeException oe)
            {
                state = 0;
                keys = "";
            }
        }

        private void SendStr(string str)
        {
            string stroke = "";
            foreach(char c in str)
            {
                stroke += "{" + c + "}";
            }
            this.Text = stroke;
            SendKeys.Send(stroke);
        }
    }
}



MacCard.Designer.cs


namespace MagCard
{
    partial class MagCard
    {
        /// <summary>
        ///  Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        ///  Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        ///  Required method for Designer support - do not modify
        ///  the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // timer1
            // 
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // label1
            // 
            this.label1.Anchor = System.Windows.Forms.AnchorStyles.None;
            this.label1.AutoSize = true;
            this.label1.Font = new System.Drawing.Font("Calibri", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
            this.label1.Location = new System.Drawing.Point(67, 104);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(408, 49);
            this.label1.TabIndex = 0;
            this.label1.Text = "Swipe Your Credit card !";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // MagCard
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(544, 251);
            this.Controls.Add(this.label1);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "MagCard";
            this.Text = "Magnetic stripe card to Key Stroke";
            this.TopMost = true;
            this.Load += new System.EventHandler(this.Form1_Load);
            this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form1_KeyPress);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.Label label1;
    }
}



Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MagCard
{
    static class Program
    {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MagCard());
        }
    }
}

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中