Javaセキュリティプログラミング:DES暗号解読


DES暗号化は最も一般的な対称暗号化アルゴリズムの一つである.「対称暗号化」とは、明文暗号化から密文へ、密文復号から明文へと同じ鍵セットに対応する「非対称暗号化」を指す.その他の一般的な対称暗号化アルゴリズムには、IDEA、RC 2、RC 4、SKIPJACK、RC 5、AESなどがある.    DES暗号化はバイト配列を暗号化したり、ファイルを暗号化したりすることができます.もちろん、復号化の前に鍵を取得する必要があります.鍵を取得するには、指定したバイト配列またはランダムな鍵を生成することができます.鍵は実は8つの長さのバイト配列です.
/**
 *        DES  
 * @throws Exception
 */
public static Key randomKey() throws Exception{
	KeyGenerator generator = KeyGenerator.getInstance("DES");
	SecretKey key = generator.generateKey();
	byte[] arrKey = key.getEncoded();
	System.out.println(Arrays.toString(arrKey));
	System.out.println("  Base64  :" + Base64.encodeBase64String(arrKey));
	System.out.println("  16    :" + Hex.encodeHexString(arrKey));
	return key;
}

/**
 *   byte        
 * @param arrKey
 * @return
 * @throws Exception
 */
public static Key getKey(byte[] arrKey) throws Exception {
	//   DES    
	DESKeySpec spec = new DESKeySpec(arrKey);
	//   DES    
	SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
	return factory.generateSecret(spec);
}
DESKeySpecクラスのコンストラクション関数から、8ビットのバイト配列のインスタンス化しか入力できないことがわかります.
public DESKeySpec(byte abyte0[])
	throws InvalidKeyException
{
	this(abyte0, 0);
}

public DESKeySpec(byte abyte0[], int i)
	throws InvalidKeyException
{
	if(abyte0.length - i < 8)
	{
		throw new InvalidKeyException("Wrong key size");
	} else
	{
		a = new byte[8];
		System.arraycopy(abyte0, i, a, 0, 8);
		return;
	}
}

鍵を取得すると、バイト配列とファイルの復号化を行うことができます.
/**
 *            
 * @param data
 * @param key
 * @return
 * @throws Exception
 */
public static byte[] encryptByteArr(byte[] data, Key key) throws Exception {
	// using DES in ECB mode
	Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
	//       Cipher  
	cipher.init(Cipher.ENCRYPT_MODE, key);
	return cipher.doFinal(data);
}
/**
 *            
 * @param data
 * @param key
 * @return
 * @throws Exception
 */
public static byte[] decryptByteArr(byte[] data, Key key) throws Exception {
	// using DES in ECB mode
	Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
	//       Cipher  
	cipher.init(Cipher.DECRYPT_MODE, key);
	return cipher.doFinal(data);
}
/**
 * DES    
 * @param file     
 * @param dest         
 * @param key   
 * @throws NoSuchAlgorithmException
 * @throws NoSuchPaddingException
 * @throws InvalidKeyException
 * @throws IOException
 */
public static void encryptFile(File file, File dest, Key key)
		throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
	Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    InputStream is = new FileInputStream(file);
    OutputStream out = new FileOutputStream(dest);
    CipherInputStream cis = new CipherInputStream(is, cipher);
    byte[] buffer = new byte[1024];
    int r;
    while ((r = cis.read(buffer)) > 0) {
        out.write(buffer, 0, r);
    }
    cis.close();
    is.close();
    out.close();
}
/**
 * DES    
 * @param file          
 * @param dest         
 * @param key   
 * @throws NoSuchAlgorithmException
 * @throws NoSuchPaddingException
 * @throws InvalidKeyException
 * @throws IOException
 */
public static void decryptFile(File file, File dest, Key key)
		throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
		IOException {
	Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.DECRYPT_MODE, key);
    InputStream is = new FileInputStream(file);
    OutputStream out = new FileOutputStream(dest);
    CipherInputStream cis = new CipherInputStream(is, cipher);
    byte[] buffer = new byte[1024];
    int r;
    while ((r = cis.read(buffer)) > 0) {
        out.write(buffer, 0, r);
    }
    cis.close();
    is.close();
    out.close();
}