Skip to content

Instantly share code, notes, and snippets.

@seyan
Created April 13, 2011 02:09
Show Gist options
  • Save seyan/916836 to your computer and use it in GitHub Desktop.
Save seyan/916836 to your computer and use it in GitHub Desktop.
データの暗号化と復号化(ファイルと文字列 それぞれ)
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.junit.Test;
public class TestFileCrypt {
private static final String ALG = "AES";
private static final int KEYSIZE = 128;
private static final int CASHE_SIZE = 2000; //最低でも2000くらいとりましょう(性能のため):HDDのブロックサイズと同じだと最高。
private static final int CAPACITY_SB = 1024; //StringBuilderの初期容量
private static final String PLAINFILE = "secret/plain.dat";
private static final String ENCRYPTFILE = "secret/encrypt.dat";
private static final String DECRYPTFILE = "secret/decrypt.dat";
@Test
public void testTextCrypt() throws Exception{
KeyGenerator keyGen = KeyGenerator.getInstance(ALG);
keyGen.init(KEYSIZE);
SecretKey key = keyGen.generateKey();
String plainFileText = getFileString(new File(PLAINFILE));
encryptFile(key, PLAINFILE, ENCRYPTFILE);
String encryptFileText = getFileString(new File(ENCRYPTFILE));
decryptFile(key, ENCRYPTFILE, DECRYPTFILE);
String decryptFileText = getFileString(new File(DECRYPTFILE));
assertNotSame( plainFileText, encryptFileText);
assertEquals( plainFileText, decryptFileText);
}
/**
* ファイルの暗号化メソッド
* @param key
* @param plainFileName
* @param cryptFileName
* @throws Exception
*/
private static void encryptFile(SecretKey key, String plainFileName, String encryptFileName) throws Exception{
Cipher cipher = Cipher.getInstance(ALG);
cipher.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream(plainFileName);
fos = new FileOutputStream(encryptFileName);
// 暗号化ストリームを用意
CipherInputStream cis = new CipherInputStream(fis, cipher); //fisと同時にcloseされるのでclose不要(内側が閉じれば閉じる)
byte[] buf = new byte[CASHE_SIZE];
int i;
while( (i = cis.read(buf)) != -1 ){
fos.write(buf,0, i);
}
}finally{
close(fis);
close(fos);
}
}
/**
* ファイルの復号化メソッド
* @param key
* @param encryptFileName
* @param decryptFileName
* @throws Exception
*/
private static void decryptFile(SecretKey key, String encryptFileName, String decryptFileName) throws Exception{
Cipher cipher = Cipher.getInstance(ALG);
cipher.init(Cipher.DECRYPT_MODE, key);
FileInputStream fis = null;
FileOutputStream fos = null;
CipherOutputStream cos = null;
try{
fis = new FileInputStream(encryptFileName);
fos = new FileOutputStream(decryptFileName);
cos = new CipherOutputStream(fos, cipher);
byte[] buf = new byte[CASHE_SIZE];
int i;
while( (i = fis.read(buf)) != -1 ){
cos.write(buf, 0, i);
}
}finally{
close(cos); //closeしないと最後の一文字が切れてしまう。
close(fos);
close(fis);
}
}
private static void close(Closeable c) throws Exception {
try {
if (c != null) {
c.close();
}
} catch (Exception e) {
throw new Exception(e);
}
}
/**
* ファイルの中身をStringにして返す
* @param file
* @return
* @throws Exception
*/
private static String getFileString(File file) throws Exception{
BufferedReader reader = null;
StringBuilder result = new StringBuilder(CAPACITY_SB);
try{
reader = new BufferedReader(new FileReader(file));
String line = null;
while((line = reader.readLine()) != null){
result.append(line);
}
}finally{
reader.close();
}
return result.toString();
}
public static void main (String[] args) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance(ALG);
keyGen.init(KEYSIZE);
SecretKey key = keyGen.generateKey();
System.out.println(getFileString(new File(PLAINFILE)));
encryptFile(key, PLAINFILE, ENCRYPTFILE);
System.out.println(getFileString(new File(ENCRYPTFILE)));
decryptFile(key, ENCRYPTFILE, DECRYPTFILE);
System.out.println(getFileString(new File(DECRYPTFILE)));
}
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.junit.Test;
public class TestTextCrypt {
private static final String ALG = "AES";
@Test
public void testTextCrypt() throws Exception{
String text = "abcdefg";
String key = "asdfghjkloiuy67t"; //16文字(128bit)
byte[] encrypted = encrypt(key, text);
assertNotSame( new String( encrypted ), text);
assertEquals( decrypt(key, encrypted), text );
}
/**
* 暗号化を行う
* @param key
* @param text
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
private byte[] encrypt(String key, String text) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
//プロバイダに依存しない形式で秘密鍵を指定
SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), ALG);
//暗号化および復号化の機能を提供するCipherオブジェクト生成
Cipher cipher = Cipher.getInstance(ALG);
cipher.init(Cipher.ENCRYPT_MODE, sksSpec);
byte[] encrypted = cipher.doFinal(text.getBytes());
return encrypted;
}
/**
* 復号化を行う
* @param key
* @param encrypted
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
private String decrypt(String key, byte[] encrypted) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), ALG);
Cipher cipher = Cipher.getInstance(ALG);
cipher.init(Cipher.DECRYPT_MODE, sksSpec);
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment