いろいろとネットの情報を参考にしながら、FeliCa LiteのMAC生成アルゴリズムができた。
そのとき、3DES暗号についてなんとなくわかったので、記録を残しておく。
3DESといってもいくつか細かくあるらしく、FeliCa LiteではCBCという方式を使っている。
これは、前ブロックの3DES計算結果を、次のブロックとxorする方式みたいだ。
それは、IVとか初期ベクタとか呼んでいる。
細かい実装は知らないが、1段目でDESエンコード、2段目でそれをDESデコード、3段目でそれをDESエンコードする。
1, 2, 3段目はそれぞれ別の鍵を用いるのが望ましいらしい(FeliCa Liteでは、1と3が同じ)。
鍵が3つとも同じだと、エンコード→デコード→エンコードとなり、DESエンコード1回分と同じになるという。
DESを3回やって、IVを自分でxorしてみたが、ちゃんと同じ結果になった。
xorする実装は好きこのんでやったわけではなく、FeliCa Liteの説明がそうなっていたからだ。
「IVはxorしてつっこむ」という方式であることを知っていたら、やってないですわ。
この辺りが、知識がないなー、と思ったところですな。
あと、24byteの鍵でちょっと迷った。
FeliCa Liteでは2つの鍵しかないので、24byteをどう埋めるのかというところの記述を探したのだが、見つからんかったのだ。
[0-7]に鍵1、[8-15]に鍵2、[16-23]に鍵1をいれると、とりあえずFeliCa Liteと同じ結果になった。
鍵を3つ別にする場合、[0-7]なのか[16-23]なのか気になるが、まあ今のところわからんですな。
できたのは、こんなソース。
8byte固定なのです。
1: /**
2: * Triple-DES暗号化
3: *
4: * @param outBuf 暗号化出力バッファ(8byte以上)
5: * @param outOffset 暗号化出力バッファへの書き込み開始位置(ここから8byte書く)
6: * @param key 秘密鍵(24byte [0-7]KEY1, [8-15]KEY2, [16-23]KEY1)
7: * @param inBuf 平文バッファ(8byte以上)
8: * @param inOffset 平文バッファの読み込み開始位置(ここから8byte読む)
9: * @param ips 初期ベクタ(8byte)
10: * @return true 暗号化成功
11: */
12: private static int enc83(byte[] outBuf, int outOffset, final byte[] key, final byte[] inBuf, int inOffset, IvParameterSpec ips) {
13: int sz = 0;
14: try {
15: // 秘密鍵を準備
16: SecretKeyFactory kf = SecretKeyFactory.getInstance("DESede");
17: DESedeKeySpec dk = new DESedeKeySpec(key);
18: SecretKey sk = kf.generateSecret(dk);
19: dk = null;
20: kf = null;
21:
22: // 暗号
23: Cipher c = Cipher.getInstance("DESede/CBC/NoPadding");
24: c.init(Cipher.ENCRYPT_MODE, sk, ips);
25: sz = c.doFinal(inBuf, inOffset, 8, outBuf, outOffset);
26:
27: } catch (Exception e) {
28: Log.e(TAG, "enc83 exception");
29: }
30: return sz;
31: }
dkとkfをnullにしているのは、参考にしたソースがそうなっていたから。
セキュリティのために鍵は使ったら0で埋めてから解放する、なんてことまでやっていた。
うーん、このあたりはJavaの知識がないといかんですな。
メモリリーク(Effective Javaで「意図しないオブジェクト保持」と書いてあるやつ)とかも全然気にしていないので、ここ以外の場所が心配である。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。