Arduinoを USB/HIDデバイス(仮想キーボード)として活用する

##本記事について
　Arduino はPCやスマフォとUSB接続したとき，自身をUSB/HIDデバイスとして認識させる機能が標準で備わっています。HID（ヒューマン・インターフェイス・デバイス）とはUSB接続のキーボードやマウス，ゲームパッドのような入出力装置のことです。この記事から一連の連載では、Arduinoを仮想キーボードとして動作させ、その活用方法をさぐってみようと思います。
##第一弾）「BadUSB(仮想キーボード)紹介」
 Arduinoを仮想キーボードとして活用する事例を調べているうちに、 BadUSBなる言葉があることを知りました。アマゾンなどでは、それを実現する製品も販売されています。BadUSB製品の多くは、 ATmega32U4というマイコンを使っていることがわかったため、BadUSBとはいかなるものかを知るためにも、まず、「ATmega32U4」マイコンを搭載した製品を使用し、どんな使い方ができるか検討しました。
##説明
###アプリケーション
 マイコンをPCやスマートフォンと接続して動かすアプリケーションを考えたとき、機種依存ではなく、Web技術を利用したクラウド連携システムが注目されています。これをWOT(※)と呼び、広く普及することが期待できます。今後のWOTの流れが見逃せないと考えます。
※Web of Things (WoT)とは、「モノの Web」という意味で、普及しているHTMLやJavaScriptなどのWeb技術を使ってIoTを利用したサービスやアプリケーションの提供を行うことを目指している。
###ブラウザーとUSBデバイスの接続
 ブラウザーとデバイスの接続に関して、主な接続の仕方には以下のようなものがあります。
 <dl><dt>(1) http / WebSocket：<dd> CloudのWebServerを介在してBrowserとデバイスを接続する。</dd></dt><dt>(2) Sound(Mic-in, Speaker-out)：<dd>音を媒体として入出力を行う。</dd></dt><dt>(3) HID(USB / Bluetooth)：<dd>キーボードやマウスといったHIDデバイスとして接続する。BadUSBと呼ばれているものもこれに属する。ブラウザー上のボタンを押すことで処理を駆動するイベントの発生ができ、マイコン主導で自動処理や定時処理を実行することが容易である。</dd></dt><dt>(4) WebUSB：<dd>JavaScriptを使用してブラウザーからUSB機器を扱うことができる。</dd></dt><dt>(5) MIDI(USB / Serial):<dd> 電子音楽の接続規格を使って接続する。音を扱うアプリには適する。反面、利用は限定的である。</dd></dt></dl>

　現時点では、(4)(5)はOSやブラウザーの種類によっては対応していないものもあります。http / WebSocketを使った接続が近年WOTの本命視されていますが、上記のうち唯一マイコン主導でイベントを発生できることから、自動化が進めやすくUSB/HIDの魅力は高いと考えます。弱点として、USBホストからUSBデバイスへの下り通信を扱うことができないことがあげられます。
###BadUSBとGoodUSB
　マイコンによるUSB/HIDデバイスを作成する場合、 BadUSBという言葉を考慮する必要があります。BadUSBとは、USBデバイス内のファームウエアを更新する仕組みを悪用できてしまうという、USBの規格に存在する脆弱性です。私は言葉の意味を広く捉え、UBSデバイスを悪用することを、BadUSBと捉えています。
 この脆弱性を悪用することで、セキュリティー問題を引き起こす仕組みを簡単に作ることができてしまいます。そんな危険性もありますが、USBデバイスは、以下の様なメリットがあり潜在能力は高いと思われます。
・キーストロークを自動化できる
・個人に配布すれば、個人特定などセキュリティーの高い使い方ができる
・プログラムが簡単。キーボードという汎用性の高いデバイスを作ることができる
　もちろん、USBデバイスの悪用はいいことではないので、Arduinoを使ったUSBデバイスを、GoodUSBとして、自分の手の届く範囲（自作のデバイスを意味します。得体のしれないUSBをPC等にさしてはいけません）で処理の自動化のために便利なツールとして使うことを目指します。
　GoodUSBとしての使い方の例として、パスワードをUSB内に保存する、セキュリティー的な使い方を実験しました。
##準備するもの
　PC (Windows10)
　Beetle BadUSB ATMEGA32U4開発ボード仮想キーボードArduino用
　開発環境は Windows版のArduino IDE  v1.8.9
##ハード構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592438/9e685fa5-f8d5-8321-2998-1de4c06e758d.png)
##ソフトウエア
```ruby:ソースコード 
/*
 *起動後、一度だけ文字列を出力するサンプル。WindowsPC接続用。
 *32U4のKBD
 */
#include "Keyboard.h"
//
void setup() {
  Keyboard.begin();
  delay(3000);
  Keyboard.print("testid"); //ID
  Keyboard.write(KEY_TAB);
  delay(100);
  Keyboard.print("test"); //password
  Keyboard.write(KEY_TAB);
  Keyboard.write(KEY_RETURN);
}
//
void loop() {
}
```
```ruby:HTML
<!DOCTYPE html><html>
<script type="text/javascript">
<!--
function t3220() {
 if (document.getElementById("IM1").value=='testid'){
  document.F1.IM1.value='OK';
  document.F1.IM1.focus();
 } else {
  document.F1.IM1.value='NG';
  document.F1.IM1.focus();
 }
 return false;
}
// -->
</script><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>HID sample</title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="1404.47">
<style type="text/css"> body {background-color: #ffffdf} </style>
<style type="text/css"> .center {text-align: center;} </style>
</head><body>
<form method="POST" name="F1">
<div class="center">
<tr>exsampleログイン画面</tr><br>
<tr>ID<input type="text" name="IM1" id="IM1" size=8>
<tr> パスワード<input type="text" name="IM2" id="IM2" size=8></tr><br><br>
<tr><input type="button" value="ログイン" onclick="return t3220()"></tr><br>
<br></div>
<p id="commandx"></p></form></body></html>
```
##実行
　準備として、WindowsPCでブラウザーを起動し、テスト用パスワード入力画面を表示しておく。
Arduino互換製品をUSBに接続すると、IDとパスワード文字列が一度だけ入力されます。
##まとめ
　USBデバイスを悪用する  BadUSBと呼ばれる言葉を理解した上で、BadUSBの潜在的な能力を節度をもって利用すれば、GoodUSBとして使えることを学んだ。また、Arduinoを USB/HIDデバイスとしてPCとつなぐことが確認できました。次回は本格的なアプリケーションを検討する予定です。