暗号・復号化のお話

まず、暗号化のアルゴリズムは結構種類があって、
JDK1.4対応分はここ を参照してもらうとして、今回使用したのは、DES-EDE(3DES)ってやつね。

3DESは、共通鍵方式で行われる。


  • 共通鍵暗号方式: 鍵はひとつ

    • ブロック暗号: データを固定長のブロック単位に区切り、それぞれのブロックを暗号化するもの。


      • DES: 鍵長は 56bit。今となっては使うべきではない。
      • 3DES: 3回 DES を繰り返したもの。2つの鍵を使うものと、3つの鍵を使うものがある。
      • AES: DES の後継とも言える暗号。



    • ストリーム暗号: データを区切らず、ひとつのデータの流れとして処理するもの。

      • RC4: ソースは非公開だったが、メーリングリストに匿名でソースが投稿され世界中の人が知るところとなった。

  • 公開鍵暗号方式: 鍵は 2つ。公開鍵と秘密鍵。

    • RSA : 最も広く使われている公開鍵暗号方式。安全性の根拠は「大きな数の素因数分解が難しいこと」
    • ElGamal (エルガマル): 安全性の根拠は「有限体上の離散対数問題が難しいこと」
    • 楕円曲線暗号:
      安全性の根拠は「楕円曲線上の離散対数問題が難しいこと」
    • ナップサック暗号: 安全性の根拠は…検索してください。現在安全でないことが数学的に証明された。

68user's page引用(謝謝)
上記は参考程度に見てもらうとして、

指定された文字列鍵を使って暗号化するんだけど、3DESの鍵に指定する場合は
24byte以上じゃないとWrong Key size でExceptionがスローされる。
実は、ここでほぼ2.5日かかった・・・orz
解決策は実に簡単で、24byteに埋めるだけw

出来上がったロジックが下記

/**
 * 暗号化を行う
 * @param bind 暗号化対象文字列
 * @return     暗号化文字列
 * @throws Exception  暗号化時の例外
 */
public String crypt3Des(String bind) throws Exception{
      String key = "abc";
      sun.misc.BASE64Encoder encoder64 = new sun.misc.BASE64Encoder();
      // Triple DES
   KeyGenerator desEdeGen = KeyGenerator.getInstance("DESede"); 
      // Generate a key
      SecretKey desEdeKey = desEdeGen.generateKey();
      
      SecretKeyFactory desEdeFactory = SecretKeyFactory.getInstance("DESede");
      DESedeKeySpec desEdeSpec = (DESedeKeySpec)
        desEdeFactory.getKeySpec(desEdeKey, javax.crypto.spec.DESedeKeySpec.class);
      byte[] rawDesEdeKey = desEdeSpec.getKey();

      DESedeKeySpec keyspec = new DESedeKeySpec(rawDesEdeKey);
      SecretKey k = desEdeFactory.generateSecret(keyspec);

      // Read 24 bytes of data from a file
      byte[] tripleDesKeyData = new byte[24]; 
      byte[] kyebyte = key.getBytes();
      for(int i=0;i<kyebyte.length;i++) {
          tripleDesKeyData[i] = kyebyte[i];
      }
      SecretKey myTripleDesKey = new SecretKeySpec(tripleDesKeyData, "DESede");
      
      byte[] ivbb = "testiv".getBytes();
      IvParameterSpec ivspec = new IvParameterSpec(ivbb);
      // Triple-DES encryption
      Cipher cipher = Cipher.getInstance("DESede");
      cipher.init(Cipher.ENCRYPT_MODE, myTripleDesKey,ivspec);
      byte[] encryptedMessage = cipher.doFinal(bind.getBytes());
      String encValue = new String(encoder64.encodeBuffer(encryptedMessage));
      return encValue;
}

/**
 * 復号化を行う
 * @param param  復号化対象文字列
 * @return       復号化文字列
 * @throws Exception  復号化時の例外
 */
public String decrypt3Des(String param) throws Exception{
    String decodeParam = "";
    Strign key = "abc";
    try{
      // Triple DES
      KeyGenerator desEdeGen = KeyGenerator.getInstance("DESede"); 
      // Generate a key
      SecretKey desEdeKey = desEdeGen.generateKey();
      
      SecretKeyFactory desEdeFactory = SecretKeyFactory.getInstance("DESede");
      DESedeKeySpec desEdeSpec = (DESedeKeySpec)
        desEdeFactory.getKeySpec(desEdeKey, javax.crypto.spec.DESedeKeySpec.class);
      byte[] rawDesEdeKey = desEdeSpec.getKey();

      DESedeKeySpec keyspec = new DESedeKeySpec(rawDesEdeKey);
      SecretKey k = desEdeFactory.generateSecret(keyspec);

      // Read 24 bytes of data from a file
      byte[] tripleDesKeyData = new byte[24];
      byte[] kyebyte = key.getBytes();
      for(int i=0;i<kyebyte.length;i++) {
          tripleDesKeyData[i] = kyebyte[i];
      }
      SecretKey myTripleDesKey = new SecretKeySpec(tripleDesKeyData, "DESede");
      
      byte[] ivbb = "testiv".getBytes();
      IvParameterSpec ivspec = new IvParameterSpec(ivbb);
      // Triple-DES encryption
      Cipher cipher = Cipher.getInstance("DESede");
      cipher.init(Cipher.DECRYPT_MODE, myTripleDesKey,ivspec);
      byte[] decParam = decoder64.decodeBuffer(param.trim());
      byte[] decryptedMessage = cipher.doFinal(decParam);

      decodeParam = new String(decryptedMessage);
      
    } catch(Exception e) {
        throw e;
    }
    return decodeParam;
}

インターネット経由でのやり取りだと、ここにさらにBase64エンコードとかされた
文字列だと思うので、Base64エンコード/デコード を暗号・復号化前に行えば
OKかと思うってか当然w

久しぶりにJavaのコードで悩んだな〜もともと暗号・復号化の知識が無い分
まず暗号・復号化の内容を理解しないといけなかったな・・・orz