「アタッシェケース#3」を正式版としました。


β版リリース時にもブログ記事を書きましたが、バグ報告もなくなり、自身で使っていても、目立った不具合がなくなってきたため、正式版としました。それでも細かいバグはまだまだありそうですので、もし何かあれば報告をいただけるとうれしいです。

アタッシェケース#3アイコンhttps://hibara.org/software/attachecase/

前述の記事でも書きましたが、Ver.2からの変更点のおさらい。

  • ファイルフォーマットの変更(Ver.3独自)
  • パスワードの扱いについての改良(RFC2898によるキー派生)
  • 暗号化、復号の処理速度の向上
  • Windows 10(タッチ操作など)に対応
  • パスワード付きZIPファイルの作成機能(おまけ)

ver.2は、2004年の開発開始からほとんど修正されることのなかったファイルフォーマットに手を入れました。冗長な部分を削除し、やや弱かったパスワード部分の扱いを改良、メモリで扱う部分を大きくし、また高速化(並列処理)に適したフォーマットにしました。

ですので、Ver.3で暗号化されたファイルは、Ver.2では復号できませんので、あらかじめご注意ください。ただし、Ver.2ファイルはVer.3では開けます。つまり上位互換です。

パスワード付きZIPファイルへの対応はおまけです(笑)。知人からの要望を受けて、入れてみました。邪魔で不評なら将来的に削除、好評なら復号処理も入れようかと思います。

技術的な変更点は、

  • .NET Frameworkでの開発
  • コードサイニング証明書の付加

今までC++Builderで開発を行ってきましたが、毎年のバージョンアップ費用がもはや個人ユースとして耐えられなくなってきたのと、無料で使える、Microsoftの「Microsoft Visual Studio Express 2015 for Windows Desktop」にした方が、より多くの人にとって、オープンソースからのプルリクエストや、フォークがしやすいのではないかと思い、乗り換えてみました。

また、暗号化ツールという性質上、セキュリティ面での使用を躊躇してしまうのを少しでも軽減しようと、コードサイニング証明書を付加してみました。法人ではなく僕個人のもので、けっこうなお値段でしたが、少しでも安心して使っていただけるようにと自腹で負担しました(泣)。

より多くの人に使っていただけるのが、開発者としては望外の喜びです。

電卓の16進から10進へ

C#で文字列をバイナリサーチする


前提として、僕のケースでは、『アタッシェケース#3』にて、ファイル先頭から固定値である「_AttacheCaseData」(16バイト)を検索していきます。それにより、自己実行形式ファイルのデータ境界が分かるようになります。

ウェブを検索してみたら、以下のサイトが近い感じがするのですが、

バイナリデータを検索する方法(vb.net)
http://www.my-hobby.jp/index.php/2012/01/vb-net2/

File.ReadAllBytes()で、一気にファイルをバイト単位での読み込みを行っています。僕のアタッシェケース#3では、出力されるファイルが、2GBを余裕で超えてくるファイルも扱う可能性もあるので、それは使えません。

そこで、File.ReadByte()を使います。知ってましたか、ReadByte();

// _AttacheCaseData
//byte[] AtcTokenByte = { 0x5F, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x43, 0x61, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61};
int[] AtcTokenByte = { 95, 65, 116, 116, 97, 99, 104, 101, 67, 97, 115, 101, 68, 97, 116, 97};

using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
{
  bool fToken = false;
  int b;
  while ((b = fs.ReadByte()) > -1)
  {
    //-----------------------------------
    // Check the token "_AttacheCaseData"
    if (b == AtcTokenByte[0])
    {
      fToken = true;
      for ( int i = 1; i < AtcTokenByte.Length; i++)
      {
        if (fs.ReadByte() != AtcTokenByte[i])
        {
          fToken = false;
          break;
        }
      }
      if ( fToken == true)
      {
        _fExecutableType = true;
        break;
      }
    }

  }// end while();

}

ReadByte()は、ストリームから1バイトずつ読み込んで行きます。ただし、返値がバイトではなく、Int32 にキャストされた符号なしバイト(int)で返ってくるのに要注意。

あらかじめ分かっている定数ならば、僕のようにint配列にしますが、場合によっては、byte値をその度にintにキャストして比較しても良いでしょう。

電卓の16進から10進へ

ちなみにbyte値をintにするには、Windowsの電卓を「プログラマ」にして「16進」→数値入力→「10進」にして、値を出しました。16進を10進に脳内変換で出来ちゃうプログラマーさんはすごいと思う(常識デスカ?)。

「アタッシェケース#3」をリリースしました


「アタッシェケース#3」のβテスト版をリリースしました。ようするにアタッシェケースの「Version.3」へのメジャーバージョンアップです。

アタッシェケース#3アイコンhttps://hibara.org/software/attachecase/   

僕が好んで使っていた統合開発環境「C++Builder」の価格高騰に伴いバージョンアップを諦め、無料で使える、Microsoftの「Microsoft Visual Studio Express 2015 for Windows Desktop」に乗り換えて、開発しました。言語は、C#ですので、ほぼフルスクラッチでの開発でした。

2004/07/25 に『ver.2』がリリースされてから、ここまで少しずつ改良を重ねてきましたが、 それはほとんどが本体側だけで、そこから生成される暗号化データの形式は、互換性を保つため、 ほぼ当時のままの設計で来ていました。

あれから年月が経つにつれて、当時の僕の拙いプログラミングから、パスワードの扱い方にやや弱い部分があることや、 暗号化するバッファの一部がとても小さく、暗号化・復号処理に時間がかかっていたことなどが分かって来ました。

また、データに格納するファイル情報が冗長になり、不要なもの、次第に使われなくなったものが多くなってきました。 そこで今回のメジャーバージョンをキッカケにして、データの仕様も全面的に見直し、再設計を行いました。 その結果、Ver.3 は、Ver.2よりも暗号強度の高いファイルを生成します。

そのため、暗号化ファイルは上位互換です。Ver.3で暗号化したファイルは、ver.2では開くことはできません。ただし、Ver.3では、Ver.2のファイルは開くことができます。

ソースコードは、GPLv3ライセンスとして、GitHubにもアップロードされています。ご興味のある方はぜひご覧いただき、フィードバックや改良案などいただけると嬉しいです(ただし、簡単な質問はググってね♥)。

また今回から、Windows 10にも正式対応しました。一応、タッチパネルを意識した作りをしたつもりですが、細かいところではどうでしょうか。タッチパネルを頻繁に使われる方で、この辺りの挙動でご不便なところがあれば、ご意見いただきたいです。

DotNetZipでEncryptionAlgorithm.WinZipAes256が選択できない


Visual Studio C#で『アタッシェケース』の新版を開発中です。その中で、パスワードZIPファイルを作成するために、DotNetZipというライブラリを使っています。

DotNetZip-Logo

ところが、以下のコードのように設定しても、コンパイルエラーとなります。

private void Zipup()
{
  if (filesToZip.Count == 0)
  {
    System.Console.WriteLine("Nothing to do.");
    return;
  }

 using (var output= new ZipOutputStream(outputFileName))
 {
   output.Password = "VerySecret!";
   output.Encryption = EncryptionAlgorithm.WinZipAes256;

   foreach (string inputFileName in filesToZip)
   {
     System.Console.WriteLine("file: {0}", inputFileName);

     output.PutNextEntry(inputFileName);
     using (var input = File.Open(inputFileName, FileMode.Open, FileAccess.Read,
                                     FileShare.Read | FileShare.Write ))
     {
       byte[] buffer= new byte[2048];
       int n;
       while ((n= input.Read(buffer,0,buffer.Length)) > 0)
       {
         output.Write(buffer,0,n);
       }
      }
    }
  }

}

Visual Studioのインテリセンスを表示させてみても、
None
PkzipWeak
Unsupported
と、肝心の「AES」が出てきません。おかしいなあ、とDotNetZipのソースを見てみたら、defineで切られているではありませんか。

AESはdefineで切られている

おそらくパスワード付きZIPのAESは、アーカイバによって解凍できなかったりするので、こういう扱いなのでしょうか。実際、DotNetZipヘルプの「EncryptionAlgorithm 列挙体」には、こう書かれていました。

Values of WinZipAes128 and WinZipAes256 are not part of the Zip specification, but rather imply the use of a vendor-specific extension from WinZip. If you want to produce interoperable Zip archives, do not use these values. For example, if you produce a zip archive using WinZipAes256, you will be able to open it in Windows Explorer on Windows XP and Vista, but you will not be able to extract entries; trying this will lead to an “unspecified error”. For this reason, some people have said that a zip archive that uses WinZip’s AES encryption is not actually a zip archive at all. A zip archive produced this way will be readable with the WinZip tool (Version 11 and beyond).

WinZipAes128 値と WinZipAes256 値は zip 仕様に含まれていませんが、WinZip のベンダー固有の拡張を使用することを意味しています。相互運用可能な Zip アーカイブを生成するには、これらの値を使用しないでください。たとえば、WinZipAes256 を使用して zip アーカイブを生成する場合、Windows XP および Vista で Windows Explorer で開くことができますが、エントリーを解凍することはできません。解凍しようとすると、「未定義のエラー」となります。このため、WinZip の AES 暗号化を使用した zip アーカイブは、実際にはまったく zip アーカイブでないと言う人もいます。この方法で生成された zip アーカイブは、WinZip ツール (バージョン 11 以降) で読み込むことができます。

ですので、AESをどうしても使いたい場合は、Visual Studioの「条件付きコンパイルシンボル」に「AESCRYPTO」を追加します。

プロジェクトのプロパティを開く

プロジェクトのプロパティを開いて、

条件付きコンパイルシンボル

追加すると、コンパイルも通り、インテリセンスにも「WinZipAes128」「WinZipAes256」の値が表示されるようになります。

JavaScriptでiOSアプリ、Androidアプリを作る環境は今はだいぶ整っている


しばらくJavaScriptでの仕事が続いていたので、じゃあ鉄は熱いうちに打つかと、作りたかったスマホゲームアプリをプライベートで、しかもJavaScript開発で一気呵成に作ってしまおうと思い立ちました。

そのゲームは以下に。もしお気に召していただけたのなら、お布施代わりに課金していただけるとうれしいです(フルバージョンになるだけの一回課金です)。

tamasabo

過去にも何度かJavaScriptでアプリ開発をやろうとして失敗したんですよね。

JavaScript開発でネイティブアプリにするフレームワークは、PhoneGapを初めとして、当時いくつか選択肢はありましたが、そのときは、どれもイマイチでした(できることが少なく、難度が高いという意味で)。

しかし、今回もCordva(PhoneGap)を使いましたが、当時とは状況がガラリと大きく変わっていたようです。

JavaScriptだけですべてを表現できるわけではない

「JavaScriptさえ書ければ、何でも表現できる!」と鼻息荒く始めるのですが、実際ハードウェアや、ネイティブ部分の壁にぶち当たると、もはやほとんど無力です。

今回でいえば、

  • アプリ内課金
  • アプリ内広告
  • ソーシャルシェア

です。中でもアプリ内課金では、iOS内のStoreKit(ネイティブ)を操作してiTunesサーバまで問い合わせるなんて、想像しただけでも、JavaScriptだけでは100%不可能。

「ああ、、、やっぱりムリだよなあ」と思って調べてたら、現在ではCordovaのプラグインが山ほどあって、アプリ内課金だけでも二つ三つ見つかる状況です。以下、今回のゲームアプリで使ったプラグインです。

アプリ課金
https://github.com/AlexDisler/cordova-plugin-inapppurchase

アプリ内広告
https://apps.admob.com
プラグイン
https://github.com/appfeel/admob-google-cordova

ソーシャルシェア
https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin

いずれもMITライセンスという素晴らしさ(たしかにGPLだとApple審査で弾かれますもんね。当たり前と言えば当たり前なのですが)。

PhpStormの万能感

phpstorm

まさか、JavaScriptによるスマホアプリ開発で、PhpStormが使えるとは思ってもみませんでした。

「PHPですよね?・・・」と知人から指摘を受けたとき、
「な、何を言ってるのか、わからねーと思うが・・・」

と、脳内ポルナレフ状態でした。たしかにPHP含めたサーバサイド開発環境じゃないのかよ、と思われますが、JavaScriptも扱うので、つまりは、iOS, Androidの統合開発環境としても使えます。

設定はとっても簡単。Cordovaのプロジェクトを作ったら、上部メニューにある「Select Run/Debug Configuration」を開きます。

select-run-and-debug

あとは、左ペインにある「PhoneGap/Cordova」を選択するだけです。

select-cordova

iOSの場合

ios-emulate

PhpStorm上で「実行」をすると、iOSの場合は、エミュレータが起動します。

別のプラグインを使えば、実機転送まで行けるそうですが、これだけでも充分すぎるくらいのデバッグ環境です。

Androidの場合

android-run

Androidの場合は、adbサーバが起動した状態で、Android端末がUSB接続されていれば、自動的に表示され、選択状態となります。

これでPhpStorm上の「実行」で、アプリはAndroid端末に転送され、デバッグできる状態になります。

一人でやっている人はすごい

以前はチームとして開発していたことがあるのですが、こうしてすべての工程を一人でこなすことになるとは思いも寄りませんでした。

今回は音関係以外、グラフィックやプログラミングは一人でやりましたが、なんと言っても大変だったのは、課金部分のデバッグでしょうか。一回だけでも課金が成功してしまえば、そのAppleアカウントはもうテストで使えなくなるからです。果たしていくつのAppleIDを作ったのやら・・・

あとは、それだけじゃないんですね。

リリースまで行くには、いろいろやるべきことがある。

プライバシーポリシーの作成(英語版も出す場合は、英語版も!)と、それを外部に置くための場所、ランディングページ(https://tamasabo.jp/)の作成をしなくてはならない。

App Storeに置くスクリーンショット画像の作成。解像度がiPhone、iPad含めて大量にあるので、地味に用意するのがたいへんだったり。

Appleの審査でのやり取りは依然として英語ですし、時差の関係か夜中の1時頃に、質問が飛んできたりします。

たいしたアプリではないので、さほど多くもないでしょうが、今後は開発者アカウントが存続するかぎり、サポートも続けていかないと、いけないのだろうなあ、と思っているところです。

s