BoringSSLが採用されたAndroid6.0について
Android6.0でOpenSSLライブラリから、BoringSSLライブラリに移行をしました。Android6.0 Changesの所にBoringSSLについての記載があるのですが、さらっと書いてあり、まぁそういうことねでさらとスルーしがちですが、具体的にどういう事なの?という事がはっきりしなかったので検証を以前行いました。
そういえばブログに記載してなかったなーと気が付いて、もう、Android6.0ネタも旬はすぎているので、誰か記事にしているだろうと思って、ググってみましたが誰も書かれていなかったので、ちょっと掘り起こして記事にしてみました。
(調査してから、期間をあけてブログに書くのはだめですね、色々と忘れてしまっています)
Android6.0 Changes
Andoid6.0のChangesのBoringSSL部分は短いので全訳すると以下となります。
AndroidはOpenSSLライブラリからBoringSSLライブラリに移行しています。当初この文章を見たときに、OS付属のライブラリをダイナミックリンクするようなアプリなんてあまりないでしょうと思っていたのですが、その後結構存在する事がある事がわかりました。
NDKを使用しているアプリケーションで、libcrypto.soやlibssl.so等NDKの一部ではない暗号化ライブラリをリンクしないでください。
これらのライブラリはパブリックなAPIではなく予告なく変更したり中断したりする可能性があります。
さらに、セキュリティの脆弱性問題に遭遇する可能性があります。
その代わりに、JNI経由でJavaの暗号APIをよびだすようにネイティブコードを変更したり、静的に暗号化ライブラリをリンクするようにしてください。
BoringSSLとは
そもそもBoringSSLてなんでしょう?
BoringSSLライブラリとは、2014年6月にGoogleがOpenSSL-1.0.2betaからforkしたライブラリです。
https://boringssl.googlesource.com/boringssl/
OpenSSLプロジェクトの慢性的な問題、パッチの増大、複雑なコード問題等を解決するために、OpenSSLをforkし新しいSSL/TSLライブラリを作成しました。OpenBSDチームも同じような理由からlibreSSLライブラリを作成しています。
日本語で解説された記事はあまりないのですが、以下等の記事を参考にされるといいと思います。
ちなみに、2014年7月にAndroidのChromeはBoringSSLに移行が終了しています
Android端末上のOpenSSLライブラリ
OpenSSLライブラリは、アンドロイドの以下の場所に格納されています。
/system/lib/libssl.so
/system/lib/libcrypto.so
Android 5.02とAndroid 6.0の実機上のライブラリファイルのサイズを比べてみました。
Android 5.02 | Android 6.0 | |
libssl.so | 275K | 145K |
libcrypto.so | 1.5M | 622K |
流石綺麗にしたという事だけありファイルサイズがかなり減っています。
Android5.02のlibssl.soの中を覗くと「OpenSSL」の文字
Android6.0のlibssl.soの中を覗くと、「BoringSSL」の文字
すごいベタな検証ですが、以上で検証終了!!
BoringSSLはOpenSSLの互換ライブラリなので、これらを使っていたアプリは基本動くんでしょうけど、これだけサイズが減ったという事はかなり変えているので、動かない物が出てくるんでしょう。
1. OpenSSLのソースを持ってきてコンパイルして、プロジェクトに組み込んで使う
2. Android端末からOpenSSLライブラリを吸い出して、プロジェクトに組み込んで使う
3. Android端末上のOpenSSLライブラリをダイナミックリンク
今回の変更により1と2は影響を受けません。3のケースが影響を受けます
3の状態を図にしてみると以下のような感じになります。(へたくそですいません)
もちろん互換ライブラリなので動く事もありますが
これらのライブラリを動的リンクしない事と明確に言っていますし、元々このようなロジックが入っているアプリケーションは、信頼性が要求される物ですので早急に対応したほうが良いと思います。
対応方法は、
脱線しますが、過去にタオソフトウェアで、tWakeUpCallMakerというアプリを作りましたが、このアプリは、アンドロイド上でアプリケーションの署名作業をするため、OpenSSLライブラリをAndroidで動作するように変更を加え(Android1.5の時代なので、当時は自分でやる必要がありました)てコンパイルして使用しました。この場合ももちろん影響は受けません。
すごいベタな検証ですが、以上で検証終了!!
BoringSSLはOpenSSLの互換ライブラリなので、これらを使っていたアプリは基本動くんでしょうけど、これだけサイズが減ったという事はかなり変えているので、動かない物が出てくるんでしょう。
どんなアプリが影響を受けるのか
クライアントアプリが、JavaのプログラムでHTTPS通信をするプログラムは、まったく影響を受けませんので安心してください。影響を受けるアプリを作った人は既に、あ?自分?という感じで気づくと思います。といってもプログラマ以外の方もいますので、簡単に解説しますと
OpenSSLライブラリを使うプログラムとしては以下の3形態があると思います。
1. OpenSSLのソースを持ってきてコンパイルして、プロジェクトに組み込んで使う
2. Android端末からOpenSSLライブラリを吸い出して、プロジェクトに組み込んで使う
3. Android端末上のOpenSSLライブラリをダイナミックリンク
今回の変更により1と2は影響を受けません。3のケースが影響を受けます
3の状態を図にしてみると以下のような感じになります。(へたくそですいません)
これらのライブラリを動的リンクしない事と明確に言っていますし、元々このようなロジックが入っているアプリケーションは、信頼性が要求される物ですので早急に対応したほうが良いと思います。
対応方法は、
- OpenSSLかBoringSSLのソースを持ってきて、アプリに組み込む
- SO内からJavaのコードを呼び出しJavaで処理してまた戻ってくるように変更
脱線しますが、過去にタオソフトウェアで、tWakeUpCallMakerというアプリを作りましたが、このアプリは、アンドロイド上でアプリケーションの署名作業をするため、OpenSSLライブラリをAndroidで動作するように変更を加え(Android1.5の時代なので、当時は自分でやる必要がありました)てコンパイルして使用しました。この場合ももちろん影響は受けません。
まとめ&広告
最初は、端末依存が多いアンドロイドOSで、3のケースのダイナミックリンク等使うアプリは殆どないと思ってました。(アプリ内臓の方が、ファイルサイズは大きくなりますが、動作は環境依存せずに安定するので、選択子としてはアプリ内臓だと思います。)しかしながら、ひょんなことから結構システムライブラリをダイナミックリンクして使われていることがわかりました。SOで提供されるライブラリを使用しており、暗号化通信等している場合は、一度チェックをしたほうが良いかと思います。(開発者じゃない方)
当初プライオリティは低かったのですが、プライオリティを上げ、RiskFinder6.0で検知するようにしました。
RiskFinderでの検知画面