自堕落な技術者の日記

基本は喰ってるか飲んでるかですが、よく趣味でカラオケ・PKI・署名・認証・プログラミング・情報セキュリティをやっています。旅好き。テレビ好きで芸能通

JSON

Android SDK 19だかJSONだかAdMobだかzipalignだかでハマった話

熱があって体調激悪ですが、なんか書いてみましたの第二弾です。

週末、自前のAndroidアプリの 手直しをしようとしててハマったので愚痴だと思って聞いてください。

Root CA Viewer Liteに証明書リストをエクスポートする機能を追加しようと思い、 幾つかのサイトを参考にしながら、でも、Android のプログラミングも超久しぶりなので ビルドどうやんだっけ?、コード署名どうやんだっけ?などもたもたしながら 2時間ほどで実機で動作することは確認できました。

実機確認はGoogle PlayにあげずにLAN内でやるわけですが、 AirDroidは すごく助かりますね。これをあげるとAndroid側がリモートサーバーになって 開発機からapkをアップしたり、SDカードみたりいろんなことができて実機テストが捗ります。

まず、zipalignでハマる

で、まぁ動いたから公開すんべぇとGoogle Playにアップしようとしたら zipalignされてないからアップロードできないと英語で怒られました。

minghaiさんの日記:apkファイルを最適化する zipalign
に説明があった。apkファイルがzipalignされてないとapk(zip)解凍の時、非常に メモリ効率が悪くなるのだそうです。

探してみるも zipalign などない。どうやら新しい Android SDK でないと 入っていないそうです。仕方ないのでAndroid SDK Managerで アップデートをかけました。Android 4.0.3 API 15 までしか入ってなかったんですが、 Android 4.4 API 19 まで上げてみます。APIのターゲットは15のままです。 ただし、Google AdMobは、コード手直ししないといけなそうだったりしたので、これだけ保留にしておきました。

で、アップデートすると、「そもそもEclipseのライブラリが古いよ」とこれまた 英語で怒られてヘコみます。これは従順に言われた通りに上げます。

参照関係に泣く

で、Root CA Viewerをリビルド、エミュレータで実行させようとすると、リビルドできない。

Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
その他にも、DEXが壊れててよめねーじゃねーかと英語で怒られます。 Eclipseのログ見ろっていってもログの場所がわからない。

Google大先生に聞いてみるとEclipseのログは $WORKSPACE/.metadata/.logにあることがわかりました。 ログにはあまり参考になりそうな情報はありませんでしたが、 多分、参照関係がおかしくなっているんでしょうね。 Google AdMobが古いせいなのかなと思い、AdMobライブラリも新しくしてみました。 一部、ソースコードやらXML設定ファイルやらを手直しして再度ビルドします。

再度ビルドしてみようとすると、

com.google.ads.AdView failed to instantiate. java.lang.ClassNotFoundException: org.json.JSONException at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
と怒られます。ええーーっ、JSON入ってないの?使っているJDKが古いのか、 Androidのライブラリが古いんでしょうねぇ。 Google大先生にJSONの件を聞いたら このページ(NoClassDefFoundError when trying to unit test JSON parsing in Android)を返してくれました。 APIのターゲットを上げると4.0そこそこのやつでは 動かなくなりそうだったので、org.jsonのソース探して、jar作って 置いてみました。

すると、またコレが出るようになりました。

Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
結局解決してなかったのね。

随分調べて このページ(Issue 61710:java.nio.BufferOverflowException When Building with 19 Build Tools) を見つけました。どうやらAndroid SDK 19 Build Toolの問題らしく、

  1. Android 19 Build Tools, API 19を削除する
  2. Target SDK を19から18に戻す
  3. extras/android/support/v7/appcompat/libs/android-support-v4.jarの参照を削除する
  4. 再度 android-support-v4.jar を追加する
なんか、書かれた通りにうまく行かない事もあったんですが、Eclipseを再起動したり、プロジェクトを閉じたり、開いたりしている うちに、書かれた方法で無事ビルドでき、動作するところまではこぎつけました。

最後にzipalignではまる

結局は署名済apkが出力される場所が間違っていたというオチなわけですが、 本来なら署名済apkを作った際に自動的にzipalignも実行されるとの事です。 結局コマンドラインでやってしまいました。

% tools/zipalign 4 RootCAViewerLite.apk RootCAViewerLite_.apk (*_.apkが出力先で署名済)
% tools/zipallgn -v -c RootCAViewerLite_.apk (チェック)
Verifying alignment of RootCAViewerLite.apk (4)...
62 res/layout/activity_cert.xml (OK - compressed)
655 res/layout/activity_main.xml (OK - compressed)
1252 res/layout/activity_textview.xml (OK - compressed)
1937 res/menu/activity_cert.xml (OK - compressed)
2256 res/menu/activity_main.xml (OK - compressed)
2604 res/menu/activity_textview.xml (OK - compressed)
2916 AndroidManifest.xml (OK - compressed)
4000 resources.arsc (OK)
7316 res/drawable-hdpi/ic_action_search.png (OK)
7788 res/drawable-hdpi/ic_launcher.png (OK)
9864 res/drawable-ldpi/ic_launcher.png (OK)
11236 res/drawable-mdpi/ic_action_search.png (OK)
11612 res/drawable-mdpi/ic_launcher.png (OK)
13272 res/drawable-xhdpi/ic_action_search.png (OK)
13828 res/drawable-xhdpi/ic_launcher.png (OK)
16458 classes.dex (OK - compressed)
570061 README (OK - compressed)
571082 jsr305_annotations/Jsr305_annotations.gwt.xml (OK - compressed)
571300 jsr305_annotations/v0_r47/V0_r47.gwt.xml (OK - compressed)
571474 META-INF/MANIFEST.MF (OK - compressed)
572232 META-INF/CERT.SF (OK - compressed)
573041 META-INF/CERT.RSA (OK - compressed)
Verification succesful
ファイルサイズが昇順になるんですね。というわけで、いろいろありましたが何とか新しいRoot CA Viewer Liteを 公開することができました。あーつかれた。

jsrsasignをNode.jsのモジュールnpmで公開してみたぞ

昨日あたりからpure JavaScriptの暗号ライブラリjsrsasignと、JSON Web Token (JWT)やJSON Web Signatures (JWS)を生成、検証できるライブラリjsjwsを合体させて、最近流行りらしいサーバーサイドJavaScriptであるNode.js用のパッケージ https://npmjs.org/package/jsrsasign として公開しています。

Node.jsでは、基本的にOpenSSLベースの標準モジュールCryptoがあって、あまりjsrsasignの出番は少ないとも思うんですが、コマンドラインインタープリタで例えばASN.1作ったり、読んだり、 JWS ができたりして結構楽しめます。そういう意味では惜しげもなくほとんどすべてのクラス、名前空間、メソッドにNode.jsからアクセスできるようにしています。

Node.jsは適当に検索してインストールしてもらうとして、jsrsasignのnpmをインストールするにはこんな感じ。

% npm install jsrsasign

で、Node.jsインタプリタを起動します。

% node

下準備としてファイル入出力とjsrsasignをロードしておきます。

> var r = require('jsrsasign');
> var fs = require('fs');

そんで、試しに暗号化されたPKCS#5 RSA秘密鍵ファイルを読み込んでみましょう。

> var pem = fs.fileReadSync('z1.prv.p5e.pem', 'ascii');
> var prvKey = r.KEYUTIL.getKey(pem, 'passwd');
試しにプリントする
> prvKey
{ n:
   { '0', 18414937 ...
ふむふむ大丈夫そうだ。

ほいで、JWS署名なんかしてみちゃいましょう。

> r.jws.JWS.sign(null, '{"alg":"RS256"}', '{"fruit":"orange"}', prvKey);
'eyJhbGciOiJSUzI1NiJ9.eyJmcnVpdCI6Im9yYW5nZSJ9.uuYgjlhRGbQyxw-Zx0sqgrbc5WNIUh7ow
M1m_lLM_JpRJuL8XdgANr7hkp09yFSxK7EzqZYrC_iMQjz72d7-wg'

読めないでしょうけど(汗)、JWSはちゃんとできてるっぽいですね。ってなわけで、コマンドラインでJWS作ったり、署名したり、ハッシュ計算したり、ASN.1作ったりいろいろできるので遊んでみてください。

今日はこんなとこで

最新記事
Categories
Archives
Twitter
記事Google検索

本ブログ内をGoogle検索
Yahoo!アクセス解析
Travel Advisor
記事検索
QRコード
QRコード
  • ライブドアブログ