情報の機密性確保のために、内容を隠蔽することを暗号化(encryption)と呼びます。 そして、暗号化する前の文を平文と呼び、 暗号から平文に戻すことを復号と呼びます。 暗号化復号の処理に使うデータをと呼びます。

共通鍵暗号方式

暗号化と復号で、どちらも同じを使う方式です。 換字方式、加算方式、転置方式などがあります。 以下に示すDES(Data Encryption Standard)の方式では、加算と転置を組み合わせています。
加算方式は、XORのビット演算を使います。 XORは、演算する2つのビットが同じであれば0、そうでなければ1にする演算です。 これを使うと、平文のビットを、鍵で1の位置だけ、反転させることができます。 得られた結果が暗号文です。これを同じキーを再び演算すると、もとの平文に戻せます。
←これで、その演算を検証ください。 参考:コード表
スイッチの画像をクリックしてビットを指定して計算します。

共通鍵暗号方式は、入力データを固定サイズ(ブロック長)に分割してから、各ブロックごとで暗号化する ブロック暗号と、連続したビット列(1ビット〜数ビットまたは1byte)ずつ暗号化するストリーム暗号があります。
代表的な共通暗号方式を以下に示します。

名称鍵サイズ方式概要
DES56bitブロック暗号以前(77年)米国の標準暗号に採用
RC440〜256bitストリーム暗号IEEE801.11bの無線通信用のWEPで採用
A5/1,A5/264bitストリーム暗号GSM携帯電話のプライバシー保護用に採用
AES128,192,256bitブロック暗号DESの後継

鍵ファイルの作成 (DESの実験)

Javaで作成したDES暗号キー作成のプログラムを、 ここよりダウンロードして実験できます。
(ソース:MakeKeyDES.java
実行例を示します。以下では、suzuki_DESKey.txtの鍵ファイルを作成しています。

Z:\security>java MakeKeyDES
適当な入力から、共通鍵を作ります。作成されるファイル名:name_DESKey.txt
 名前入力>suzuki
 (起動時間で乱数を作る場合は、単にEnterを入力ください)
 乱数の種を数値で入力>12345678
作成した共通鍵 =549441917164084766010242426951(先頭8byteを使用)
Bu9Xs5wx768= 06 EF 57 B3 9C 31 EF AF
suzuki_DESKey.txtの鍵ファイル生成終了

Z:\security>

作成された鍵ファイル(suzuki_DESKey.txt)の内容を示します。

Bu9Xs5wx768=

なお、このコードはBase64と呼ばれる表記です。 (メールなどでよく使われるもので、バイナリーデータを効率よくテキストデータで表現するためのコードです。)

暗号化 (DESの実験)

Javaで作成した暗号化プログラムを、 ここよりダウンロードして実験できます。
(ソース:EncryptDES.java
実行例を示します。まず、次の平文を『平文.txt』で用意します。

6月29日に
隠れて、逢いましょう。

次のように実行します。まず、鍵を選択するダイアログが現れます。 それに対して『suzuki_DESKey.txt』のファイルを選んでいます。 次に上記で作成した『平文.txt』を選択しています。

Z:\security>java EncryptDES
_DESKeyファイルを読み取ります。

読み取り内容:Bu9Xs5wx768=byte列 06 EF 57 B3 9C 31 EF AF
暗号化対象を読み取ります。
Z:\security\suzuki_DESKey.txtで、
Z:\security\平文.txtのファイルを暗号化し、
Z:\security\平文.txt.暗号.txt のファイル生成終了

Z:\security>

上記実行で、次の『平文.txt.暗号.txt』の名前の暗号化されたファイルが作成されます。

tQKIT4nIgwAQ8K5y4VRc6x3KKO4lf5HJInlD3AFZTYak319iPz4CGw==

復号 (DESの実験)

Javaで作成した復号プログラムを、 ここよりダウンロードして実験できます。
(ソース:DecryptDES.java
実行例を示します。

次のように実行します。まず、鍵を選択するダイアログが現れます。 それに対して『suzuki_DESKey.txt』のファイルを選んでいます。 次に上記で作成した『平文.txt.暗号.txt』を選択しています。
これによって出来上がる『平文.txt.暗号.txt.復号.txt』が 復号したファイルで『平文.txt』と内容が一致するはずです。

Z:\security>java DecryptDES
_DESKeyファイルを読み取ります。

読み取り内容:Bu9Xs5wx768=byte列 06 EF 57 B3 9C 31 EF AF
復号対象を読み取ります。
Z:\security\suzuki_DESKey.txtで、
Z:\security\平文.txt.暗号.txtのファイルを暗号化し、
Z:\security\平文.txt.暗号.txt.復号.txt のファイル生成終了

Z:\security>

上記各ソースファイルを以下に示します。

MakeKeyDES.java

import java.io.*;//FileInputStream, FileOutputStream;
import javax.swing.JFileChooser;//ファイルオープンダイアログ用
import java.math.BigInteger;//任意精度の整数クラス
import javax.crypto.SecretKeyFactory;//秘密 (対称) 鍵ファクトリ操作用クラス
import javax.crypto.spec.DESKeySpec;//DES 鍵用インターフェイス
import java.security.Key;//すべての鍵の最上位インタフェース
import javax.crypto.SecretKey;//秘密 (対称) 鍵用インターフェイス(上記Keyを継承)
import javax.crypto.Cipher;//暗号化および復号化の機能の提供クラス

class MakeKeyDES
{
	static final char[] B64 = { //変換に使うテーブル 64進(6bit分)を  16桁 4行で表現している 
	'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' ,'P',//00〜0Fの64進に対応する文字
	'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,'a' ,'b' ,'c' ,'d' ,'e' ,'f',//10〜1Fの64進対応に対応する文字
	'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v',//20〜2Fの64進対応に対応する文字
	'w' ,'x' ,'y' ,'z' ,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'+' ,'/' //30〜3Fの64進対応に対応する文字
	};

	//引数のbyte配列を、Base64の文字列に変換して返す。
	public static String encode64(byte a[])	{
		if (a.length == 0) return "";
		StringBuffer s = new StringBuffer();//変換した文字列記憶用
		int cnt3 = 0;	//3yteカウント用
		long data = 0;	//変換対象用:3byteを設定し、4文字で取り出す
		int idx = 0;
		do{
			//data に 3byte分を設定
			data <<= 8;
			if (idx < a.length){
				if (a[idx] >= 0){//Javaは符号なしがないので、if文で処理を変える
					data += a[idx];
				} else {
					data += 256 + a[idx]; //符号なしのコードに変換して加算
				}
			}
			cnt3++;
			if (cnt3 == 3){//3byteごとに変換

				//dataを4個の64進に対応する文字に変換
				int i = (int)(data / (64 * 64 * 64));
				//System.out.println(data + "," + i + "," + 256 * 256 * 256);
				s.append(B64[i]);//1文字目

				data = data % (64 * 64 * 64);
				i = (int)(data / (64 * 64));
				s.append(B64[i]);//2文字目

				data = data % (64 * 64);
				i = (int)(data / (64));
				s.append(B64[i]);//3文字目

				data = data % 64;
				s.append(B64[(int)data]);//4文字目

				data = 0;	//次の変換データの準備
				cnt3 = 0;
			}
			idx++;
		} while (idx < a.length || cnt3 != 0);
		int len = s.length(); //文字列の長さ
		String rtnval = "";
		if (a.length % 3 == 2) {
			return s.substring(0, len - 1) + "=";
			
		} else if (a.length % 3 == 1){
			return s.substring(0, len - 2) + "==";
			
		} else 	{
			return s.toString();
		}
	}

	public static void main(String arg[]) throws Exception{
		java.util.Scanner stdin = new java.util.Scanner(System.in);
		System.out.println("適当な入力から、共通鍵を作ります。作成されるファイル名:name_DESKey.txt");
		System.out.print(" 名前入力>");
		String name = stdin.nextLine();
		System.out.println(" (起動時間で乱数を作る場合は、単にEnterを入力ください)");
		System.out.print(" 乱数の種を数値で入力>");
		String r = stdin.nextLine();
		
		// DES 初期化
		SecretKeyFactory keyFactory	= SecretKeyFactory.getInstance("DES");

		java.util.Random rand = new java.util.Random();//システム起動時間利用
		try{
			rand = new java.util.Random(Integer.parseInt(r));//適当な乱数の種
		} 
		catch(Exception e) { }
		
		BigInteger secretNum = new BigInteger(100, rand);
		System.out.println("作成した共通鍵 =" + secretNum + "(先頭8byteを使用)");

		// それを元に DES の鍵を生成する(先頭8byteのみが使用される)
		DESKeySpec keySpec = new DESKeySpec(secretNum.toByteArray());
		
		byte []keys = keySpec.getKey();
		String b64 = encode64(keys);
		System.out.print(b64);
		for(int k = 0; k < keys.length; k++) System.out.printf(" %02X" , keys[k]);
		System.out.println();

		FileOutputStream out = new FileOutputStream(name + "_DESKey.txt");
		out.write(b64.getBytes());//ベース64にエンコードしてファイル化
		out.close();
		System.out.println(name + "_DESKey.txtの鍵ファイル生成終了");
	}
}


EncryptDES.java

import java.io.*;//FileInputStream, FileOutputStream;
import javax.swing.JFileChooser;//ファイルオープンダイアログ用
import java.math.BigInteger;//任意精度の整数クラス
import javax.crypto.SecretKeyFactory;//秘密 (対称) 鍵ファクトリ操作用クラス
import javax.crypto.spec.DESKeySpec;//DES 鍵用インターフェイス
import java.security.Key;//すべての鍵の最上位インタフェース
import javax.crypto.SecretKey;//秘密 (対称) 鍵用インターフェイス(上記Keyを継承)
import javax.crypto.Cipher;//暗号化および復号化の機能の提供クラス

class EncryptDES {
	static final char[] B64 = { //変換に使うテーブル 64進(6bit分)を  16桁 4行で表現している 
	'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' ,'P',//00〜0Fの64進に対応する文字
	'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,'a' ,'b' ,'c' ,'d' ,'e' ,'f',//10〜1Fの64進対応に対応する文字
	'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v',//20〜2Fの64進対応に対応する文字
	'w' ,'x' ,'y' ,'z' ,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'+' ,'/' //30〜3Fの64進対応に対応する文字
	};

	//引数のbyte配列を、Base64の文字列に変換して返す。
	public static String encode64(byte a[])	{
		if (a.length == 0) return "";
		StringBuffer s = new StringBuffer();//変換した文字列記憶用
		int cnt3 = 0;	//3yteカウント用
		long data = 0;	//変換対象用:3byteを設定し、4文字で取り出す
		int idx = 0;
		do	{
			//data に 3byte分を設定
			data <<= 8;
			if (idx < a.length)	{
				if (a[idx] >= 0)
				{//Javaは符号なしがないので、if文で処理を変える
					data += a[idx];
				} else 	{
					data += 256 + a[idx]; //符号なしのコードに変換して加算
				}
			}
			cnt3++;
			if (cnt3 == 3) 	{//3byteごとに変換

				//dataを4個の64進に対応する文字に変換
				int i = (int)(data / (64 * 64 * 64));
				//System.out.println(data + "," + i + "," + 256 * 256 * 256);
				s.append(B64[i]);//1文字目

				data = data % (64 * 64 * 64);
				i = (int)(data / (64 * 64));
				s.append(B64[i]);//2文字目

				data = data % (64 * 64);
				i = (int)(data / (64));
				s.append(B64[i]);//3文字目

				data = data % 64;
				s.append(B64[(int)data]);//4文字目

				data = 0;	//次の変換データの準備
				cnt3 = 0;
			}
			idx++;
		} while (idx < a.length || cnt3 != 0);
		int len = s.length(); //文字列の長さ
		String rtnval = "";
		if (a.length % 3 == 2) {
			return s.substring(0, len - 1) + "=";
		} else if (a.length % 3 == 1) {
			return s.substring(0, len - 2) + "==";
		} else {
			return s.toString();
		}
	}

	//Base64の文字列から、バイナリデータを求める。
	public static byte[] decode64(String s)	{
		int n = s.length() * 3 / 4;
		if (s.endsWith("==")) n -= 2;
		else if (s.endsWith("=")) n -= 1;
		byte[] bi = new byte[n];
		int iset = 0;
		int len = s.length();
		int data = 0;
		int icount = 0;
		int i;
		try	{
			for (i = 0; i < len; i++) { //文字を順番に処理する。
				char c = s.charAt(i);
				data <<= 6;// 6ビットシフト
				icount++;
				if (c != '=') {
					//Base64の文字から、テーブル内のインデックスを求める。
					if (c >= 'A' && c <= 'Z') {
						data |= c - 'A';
					} else if (c >= 'a' && c <= 'z') {
						data |= c - 'a' + 0x1a;
					} else if (c >= '0' && c <= '9') {
						data |= c - '0' + 0x34;
					} else if (c == '+') {
						data |= 0x3e;
					} else if (c == '/') {
						data |= 0x3f;
					}
				}
				if (icount == 4) {
					icount = 0;
					bi[iset++] = (byte)((data >> 16) & 0x00ff);
					bi[iset++] = (byte)((data >> 8) & 0x00ff);
					bi[iset++] = (byte)(data & 0x00ff);
					data = 0;
				}
			}
		}
		catch (ArrayIndexOutOfBoundsException e) {
			//  =文字など無効なデータ分の設定は無視 
			//System.out.println( iset + "::::" + e.toString());
		}
		return bi;
	}


	public static void main(String arg[]) throws Exception{
		java.util.Scanner stdin = new java.util.Scanner(System.in);
		
		System.out.println("_DESKeyファイルを読み取ります。");
		javax.swing.JFileChooser chooser = new javax.swing.JFileChooser(new File("."));
		chooser.setDialogTitle("DESのkeyのファイル選択ください。");
		System.out.println();
		if (chooser.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
			System.exit(0);
		String keyfile = chooser.getSelectedFile().getPath();//keyファイルパス
		File file = new File(keyfile);
		int  size = (int)file.length();
		byte bi[] = new byte[size];//ファイルサイズのbyte配列を用意。
		FileInputStream is = new FileInputStream(keyfile);
		is.read(bi);//ファイルバイナリーを一括読み取る。
		is.close();	//ファイルを閉じる。
		String keyBsae64 = new String(bi);
		System.out.print("読み取り内容:" + keyBsae64 + "byte列");
		byte[] keys = decode64(keyBsae64);
			
		// DES 初期化、キーを記憶
		SecretKeyFactory keyFactory	= SecretKeyFactory.getInstance("DES");
		DESKeySpec keySpec = new DESKeySpec(keys);
		SecretKey secretKey = keyFactory.generateSecret(keySpec);
		for (int k = 0; k < keys.length; k++) System.out.printf(" %02X", keys[k]);
		System.out.println();

		System.out.println("暗号化対象を読み取ります。");
		chooser.setDialogTitle("暗号化対象のファイル選択ください。");
		File srcFile = new File("");
		chooser.setSelectedFile(srcFile);
		if (chooser.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
			System.exit(0);
		srcFile = chooser.getSelectedFile();
		size = (int)srcFile.length();
		byte[] datas = new byte[size];//ファイルサイズのbyte配列を用意。
		is = new FileInputStream(srcFile);
		is.read(datas);//ファイルバイナリーで一括読み取る。
		is.close();	//ファイルを閉じる。

		//keysで、datasを暗号して、outbufferに記憶する。
		Cipher cipher = Cipher.getInstance("DES");//ストリームやブロック暗号のフレームワーク取得
		cipher.init(Cipher.ENCRYPT_MODE, secretKey);//初期化(modeで暗号化なのか復号化なのかの指定)
		byte[] outbuffer = cipher.doFinal(datas);//modeによる暗号や復号の継続処理を行い、結果を返す

		//暗号化したデータをBase64に変換してファイル化
		keyBsae64 = encode64(outbuffer);
		FileOutputStream out = new FileOutputStream(srcFile + ".暗号.txt");
		out.write(keyBsae64.getBytes());
		out.close();

		System.out.println(keyfile + "で、\n" 
		+ srcFile + "のファイルを暗号化し、\n" 
		+ srcFile + ".暗号.txt のファイル生成終了");
	}
}

DecryptDES.java

import java.io.*;//FileInputStream, FileOutputStream;
import javax.swing.JFileChooser;//ファイルオープンダイアログ用
import javax.crypto.SecretKeyFactory;//秘密 (対称) 鍵ファクトリ操作用クラス
import javax.crypto.spec.DESKeySpec;//DES 鍵用インターフェイス
import java.security.Key;//すべての鍵の最上位インタフェース
import javax.crypto.SecretKey;//秘密 (対称) 鍵用インターフェイス(上記Keyを継承)
import javax.crypto.Cipher;//暗号化および復号化の機能の提供クラス

class DecryptDES {
	static final char[] B64 = { //変換に使うテーブル 64進(6bit分)を  16桁 4行で表現している 
	'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' ,'P',//00〜0Fの64進に対応する文字
	'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,'a' ,'b' ,'c' ,'d' ,'e' ,'f',//10〜1Fの64進対応に対応する文字
	'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v',//20〜2Fの64進対応に対応する文字
	'w' ,'x' ,'y' ,'z' ,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'+' ,'/' //30〜3Fの64進対応に対応する文字
	};

	//引数のbyte配列を、Base64の文字列に変換して返す。
	public static String encode64(byte a[]) {
		if (a.length == 0) return "";
		StringBuffer s = new StringBuffer();//変換した文字列記憶用
		int cnt3 = 0;	//3yteカウント用
		long data = 0;	//変換対象用:3byteを設定し、4文字で取り出す
		int idx = 0;
		do {
			//data に 3byte分を設定
			data <<= 8;
			if (idx < a.length) {
				if (a[idx] >= 0)
				{//Javaは符号なしがないので、if文で処理を変える
					data += a[idx];
				} else {
					data += 256 + a[idx]; //符号なしのコードに変換して加算
				}
			}
			cnt3++;
			if (cnt3 == 3) {//3byteごとに変換

				//dataを4個の64進に対応する文字に変換
				int i = (int)(data / (64 * 64 * 64));
				//System.out.println(data + "," + i + "," + 256 * 256 * 256);
				s.append(B64[i]);//1文字目

				data = data % (64 * 64 * 64);
				i = (int)(data / (64 * 64));
				s.append(B64[i]);//2文字目

				data = data % (64 * 64);
				i = (int)(data / (64));
				s.append(B64[i]);//3文字目

				data = data % 64;
				s.append(B64[(int)data]);//4文字目

				data = 0;	//次の変換データの準備
				cnt3 = 0;
			}
			idx++;
		} while (idx < a.length || cnt3 != 0);
		int len = s.length(); //文字列の長さ
		String rtnval = "";
		if (a.length % 3 == 2) {
			return s.substring(0, len - 1) + "=";
		} else if (a.length % 3 == 1) {
			return s.substring(0, len - 2) + "==";
		} else {
			return s.toString();
		}
	}

	//Base64の文字列から、バイナリデータを求める。
	public static byte[] decode64(String s) {
		int n = s.length() * 3 / 4;
		if (s.endsWith("==")) n -= 2;
		else if (s.endsWith("=")) n -= 1;
		byte[] bi = new byte[n];
		int iset = 0;
		int len = s.length();
		int data = 0;
		int icount = 0;
		int i;
		try {
			for (i = 0; i < len; i++) { //文字を順番に処理する。
				char c = s.charAt(i);
				data <<= 6;// 6ビットシフト
				icount++;
				if (c != '=') {
					//Base64の文字から、テーブル内のインデックスを求める。
					if (c >= 'A' && c <= 'Z') {
						data |= c - 'A';
					} else if (c >= 'a' && c <= 'z') {
						data |= c - 'a' + 0x1a;
					} else if (c >= '0' && c <= '9') {
						data |= c - '0' + 0x34;
					} else if (c == '+') {
						data |= 0x3e;
					} else if (c == '/') {
						data |= 0x3f;
					}
				}
				if (icount == 4) {
					icount = 0;
					bi[iset++] = (byte)((data >> 16) & 0x00ff);
					bi[iset++] = (byte)((data >> 8) & 0x00ff);
					bi[iset++] = (byte)(data & 0x00ff);
					data = 0;
				}
			}
		}
		catch (ArrayIndexOutOfBoundsException e) {
			//  =文字など無効なデータ分の設定は無視 
			//System.out.println( iset + "::::" + e.toString());
		}
		return bi;
	}

	// DES による暗号化と復号
	static public void useDES(int mode, Key key, InputStream in, OutputStream out) throws Exception
	{
		Cipher cipher = Cipher.getInstance("DES");//ストリームやブロック暗号のフレームワークを提供
		cipher.init(mode, key);//初期化(modeで暗号化なのか復号化なのかの指定)
		byte[] data = new byte[1024];//バッファ
		int len;
		while ((len = in.read(data)) != -1)	{//ソースをバッファに読み取り
			byte[] outbuffer = cipher.update(data, 0, len);//modeによる暗号や復号の継続処理を行い、結果を返す
			out.write(outbuffer);//ファイルに書き込み
		}
		byte[] bytes = cipher.doFinal();//ブロックやフィードバックの端数処理
		if (bytes != null) out.write(bytes);//端数を書き込む
		out.flush();
	}

	public static void main(String arg[]) throws Exception{
		java.util.Scanner stdin = new java.util.Scanner(System.in);
		
		System.out.println("_DESKeyファイルを読み取ります。");
		javax.swing.JFileChooser chooser = new javax.swing.JFileChooser(new File("."));
		chooser.setDialogTitle("DESのkeyのファイル選択ください。");
		System.out.println();
		if (chooser.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
			System.exit(0);
		String keyfile = chooser.getSelectedFile().getPath();//keyファイルパス
		File file = new File(keyfile);
		int  size = (int)file.length();
		byte bi[] = new byte[size];//ファイルサイズのbyte配列を用意。
		FileInputStream is = new FileInputStream(keyfile);
		is.read(bi);//ファイルバイナリーを一括読み取る。
		is.close();	//ファイルを閉じる。
		String keyBsae64 = new String(bi);
		System.out.print("読み取り内容:" + keyBsae64 + "byte列");
		byte[] keys = decode64(keyBsae64);
			
		// DES 初期化、キーを記憶
		SecretKeyFactory keyFactory	= SecretKeyFactory.getInstance("DES");
		DESKeySpec keySpec = new DESKeySpec(keys);
		SecretKey secretKey = keyFactory.generateSecret(keySpec);
		for (int k = 0; k < keys.length; k++) System.out.printf(" %02X", keys[k]);
		System.out.println();

		System.out.println("復号対象を読み取ります。");
		chooser.setDialogTitle("復号対象のファイル選択ください。");
		File srcFile = new File("");
		chooser.setSelectedFile(srcFile);
		if (chooser.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
			System.exit(0);
		srcFile = chooser.getSelectedFile();
		size = (int)srcFile.length();
		byte[] datas = new byte[size];//ファイルサイズのbyte配列を用意。
		is = new FileInputStream(srcFile);
		is.read(datas);//ファイルバイナリーで一括読み取る。
		is.close();	//ファイルを閉じる。

		//データをBase64からデコードして、配列に記憶します。
		keyBsae64 = new String(datas);
		datas = decode64(keyBsae64);
		
		//keysで、datasを暗号して、outbufferに記憶する。
		Cipher cipher = Cipher.getInstance("DES");//ストリームやブロック暗号のフレームワーク取得
		cipher.init(Cipher.DECRYPT_MODE, secretKey);//初期化(modeで暗号化なのか復号化なのかの指定)
		byte[] outbuffer = cipher.doFinal(datas);//ブロックやフィードバックの端数処理

		FileOutputStream out = new FileOutputStream(srcFile + ".復号.txt");
		out.write(outbuffer);
		out.close();

		System.out.println(keyfile + "で、\n" 
		+ srcFile + "のファイルを復号し、\n"
		+ srcFile + ".復号.txt のファイル生成終了");
	}
}