アーカイブ : 2013年 11月

Surface Pro 2 256GBを買ったお話

どうも、hide92795です。

なんだかんだで持ち歩けるPCが必要になり、ちょうど最近発売になったSurface Pro 2を買ってきました。

CA3G0141

モデルは256GBの方です。

ヨドバシやビックでは売り切れており、少し遠いヤマダ電機まで行くことになりましたw

初期セットアップはほかのサイトでもオススメされている通りローカルアカウントとして行いました。

アカウント作成後の画面で一度謎の再起動が入って、再度アカウント作成をするはめになりました。

この時、前に作ったのが残ってしまったのか、別の名前じゃないと作れなくなっていました。

CA3G0142

初期セットアップ後はオンラインとの接続や必要なアプリのインストールやらを行いました。

動作も快適で、何より一番感動したのは起動時間の短さです

保護フィルムはMIYAVIXのOverLay Brilliant for Surface Pro 2 / Pro

ケースはELECOMのTB-02ZSBIBHBK

マウスはロジクールのBluetoothマウスのM557を一緒に購入しました。

ケースは10.1インチ向けで入らないかとおもいきや、メーカー側で対応のマークが出ていたので買ったところ、ジャストサイズでした

もち運びが楽でWindowsが使えるというのはやっぱりいいですね

ではノシ

JavaとJavaScriptでRSA鍵交換とAES暗号化

どうも、hide92795です。

Bukkit RemoteControllerのBukkitDev上に「iPhone(WinPhone)のも作ってくれ」という要望が結構あったので、本来は来年にMacを買ってからネイティブアプリとして作る予定でしたが、なんか審査に通らない気がしてきたので、Webアプリとして作ることにしました。

JavaScriptなにこれ?おいしいの?状態からのスタートでしたが、なんとか1週間でメインの通信可能な状態まで持って行くことが出来ました。

というわけで、今回はそこでやっていたJavaとJavaScript間での暗号化について書いていこうと思います。


自分の実装ではサーバー側がJava、クライアント側がJavaScript、

Java側でRSA鍵を生成、RSA公開鍵をJavascriptへ送信、Javascriptで生成したAES共通鍵をRSAで暗号化して送信、Java側でそれを復号という手順になっています。

また、通信の方法はWebSocket(Java側はTooTallNate/Java-WebSocket、JavaScript側はデフォルトのもの)を使っています。

まず、Java側でのRSA鍵の生成から

WebSocketで通信する際には、普通の文字(String)で送信できるので、ModulesとPublicExponentを16進数の文字列表現に変換して、コロンでつなげています。

次に、JavaScript側でのAES鍵作成とそれの暗号化へ

JavaScript側での暗号化では、RSA暗号化に以下のものを使用します。

  1. RSA and ECC in JavaScript : http://www-cs-students.stanford.edu/~tjw/jsbn/
    • jsbn.js, jsbn2.js, prng4.js, rng.js, base64.jsを使用
  2. A Client-Side JavaScript RSA Encrypter : http://www.peterrowntree.com/?d0=papers/clientRSA
    • rsa.jsを使用
  3. crypto-js : http://code.google.com/p/crypto-js/
    • aes.js, pbkdf2.jsを使用

AESキーはPBKDF2でランダムに生成(random_strは指定された文字数の英数字文字列を返す関数)

受信した文字列をコロンで区切って、それからRSAKeyを作成。

rsa.encryptで返されるのは、16進数文字列なので、crypto-jsでBase64に変換

Base64に変換したものをJava側に送り返します。

ちなみに、この部分をJavaで行うと、こんな感じになります。

違いは、AES鍵を生成する際にUUIDを使用しているくらいですかね

次はJava側での復号化

ここで出てきたbyte[] keyがAES暗号鍵です。


ここからはAESを使った暗号化です。

まず、Java側での暗号化はこんな感じです

モードがAES/CBC/PKCS5なので、IVを送る必要があります。

このIVを送るために、IVと暗号化したデータをそれぞれBase64で符号化、連結しているので多少ややこしくなってしまっています。

(Java同士の実装だと、byte[]を連結させればよかったのですが、JSと組み合わせた時にIVの長さが15byteになったりと不都合があったのでこうなりました)

次に、Java側での復号化

まぁ、暗号化とは逆な感じですね。

最初にコロンで区切ってあるIVと暗号文を分け、それぞれを復号、交換したAES鍵を使用して復号化といった感じです。

次はこれを作り始めて一番時間がかかったJavaScript側の実装です。

まずは暗号化のほうから

やっている事は

  1. 暗号化するデータをWordArrayに変換
  2. IVをランダムに生成
  3. データを暗号化
  4. IVと暗号化したデータをそれぞれBase64化
  5. それらをコロンでつなげる

と言った感じです。

最後は復号化の部分です

一番の謎は、CryptoJS.AES.decryptに渡すencryptedの中身にivとkeyを渡さないとエラーが出るということです。


JavaScriptは引数にどのクラス?の変数を渡していいのかがわかりにくいのでもう大変でしたw

あとthisの仕組みが未だによくわからん(´・ω・`)

まぁ、とりあえずは動いているので、細かな修正は色々組み上げて大分わかってきてからにしましょうかね

ではノシ