2011/09/04

[java]DESede-CBC暗号化

いろいろとネットの情報を参考にしながら、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 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。