Hatena::Groupandroid

keigoiの日記

 | 

2010-02-14

WebView のhttpsリダイレクト非効率の改善ハック

21:33

先のエントリ では,Android の webブラウザコンポーネントにおける httpsプロトコルでリダイレクトが発生した時の非効率さについて説明した。問題のコードは Android SDK の一部なので、改善には Android のパッチなり次のバージョンなりを待つしかないように見える。

しかし WebView をコントロールできる場合は, 無駄な 証明書の検証を行わないように ハックできる。

注意

おそらく大丈夫だと思うが,必要なSSL証明書の検証が省略されることで脆弱性を導入するかもしれない。無保証。

どこを直すのか

android.net.http.CertificateChainValidator で、 SSLParameters.getDefaultTrustManager().checkServerTrusted(...) を呼び出している。

SSLParameters の static フィールド defaultTrustManager を、自前で作成したより効率のよい trustmanager に差し替える。

やり方

  1. 問題の X509TrustManager#checkServerTrusted について、二回目以降の実行は前回の引数と同じであれば 検証を省略するラッパークラスを準備する
  2. 1. で作成したクラスを,標準の X509TrustManager にラップする。 このオブジェクトは private static なフィールドに保存されているので、 リフレクションを用いて 設定する。

TrustManager のラッパークラス

	public class MyTM implements X509TrustManager {
		X509TrustManager delegate;
		X509Certificate[] memoChain;
		String memoAuth;
		MyTM(X509TrustManager delegate) {
			this.delegate = delegate;
		}
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			delegate.checkClientTrusted(chain, authType);
		}
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			Log.d("MyTM", "checkServerTrusted tweak enter!");
			if(chain!=null && memoChain!=null && Arrays.deepEquals(chain, memoChain) && authType!=null & authType.equals(memoAuth)) {
				Log.d("MyTM", "checkServerTrusted tweak memoization exit!");
				return;
			}
			delegate.checkServerTrusted(chain, authType);
			memoChain = chain; memoAuth = authType;
			Log.d("MyTM", "checkServerTrusted tweak non-memoization exit!");
		}
		public X509Certificate[] getAcceptedIssuers() {
			return delegate.getAcceptedIssuers();
		}
	}

ラッパーの設定

	public void tweak() {
		try {
			Class<SSLParameters> c = SSLParameters.class;
			Field f = c.getDeclaredField("defaultTrustManager");
			f.setAccessible(true);
			Object rawtm = f.get(null);
			if(rawtm==null) {
				throw new RuntimeException("defaultTrustManager is null");
			}
			f.set(null, new MyTM((X509TrustManager)rawtm));
		} catch (NoSuchFieldException e) {
			Log.e("tweak", "tweak error", e);
		} catch (IllegalAccessException e) {
			Log.e("tweak", "tweak error", e);
		} catch(RuntimeException e) {
			Log.e("tweak", "tweak error", e);
		}
	}

パフォーマンス向上

f:id:keigoi:20100214213019p:image

二度目以降のcheckServerTrustedはメモ化され、 TrustManagerImpl#checkServerCertificate の呼び出しは 1回だけになっていることがわかる。

どれだけ信用できる結果かはわからないが、単純な比較では 30% 実行時間が減少している。

ftpvtpwmiiftpvtpwmii2013/12/16 20:34pxvmpboespje, <a href="http://www.qpbhbgnbvx.com/">dtfdqbcqht</a> , [url=http://www.ckkyewslib.com/]hhzgxtkrro[/url], http://www.egyhcpqtlh.com/ dtfdqbcqht

hicifwmpxphicifwmpxp2014/04/02 17:06kelxkboespje, http://www.xtkhjtrnez.com/ eksjjehhda

adptmiayeaadptmiayea2014/04/04 23:09xwudrboespje, <a href="http://www.jlzaywbozl.com/">ikygfubsrd</a>

ncsulskzvxncsulskzvx2014/04/07 07:22uvxwgboespje, <a href="http://www.ngagyimplw.com/">jlkerggony</a>

fyiglykapifyiglykapi2014/04/10 16:25qwmrqboespje, http://www.fjuhqflopb.com/ ubxqecjyck

OpenOpen2015/10/09 18:07That's a smart way of looinkg at the world.

SangkaraSangkara2015/10/11 12:33I'll try to put this to good use <a href="http://trkzjhwkojz.com">imiylmatede.</a>

ObaderinObaderin2015/10/13 08:47That's the best answer by far! Thanks for <a href="http://gmobadow.com">coniutbrting.</a>

FloraFlora2015/10/13 15:51No more s***. All posts of this quiltay from now on http://lsrjighj.com [url=http://orhdmadqxee.com]orhdmadqxee[/url] [link=http://jsnydvnulso.com]jsnydvnulso[/link]

CherryCherry2016/02/03 18:11That adssderes several of my concerns actually.

MarlienMarlien2016/02/10 19:28This makes <a href="http://egvfinmzfdo.com">evrhtyeing</a> so completely painless.

トラックバック - http://android.g.hatena.ne.jp/keigoi/20100214
 |