此4种文件加密方式,均验证(7501)
代码一
public boolean AESCipher(int cipherMode, String sourceFilePath, String targetFilePath, String seed) {
if (cipherMode != Cipher.ENCRYPT_MODE && cipherMode != Cipher.DECRYPT_MODE) {
return false;
}
boolean result = false;
FileChannel sourceFC = null;
FileChannel targetFC = null;
try{
File sourceFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
sourceFC = new RandomAccessFile(sourceFile, "r").getChannel();
targetFC = new RandomAccessFile(targetFile, "rw").getChannel();
byte[] rawkey = getRawKey(seed.getBytes());
SecretKeySpec secretKey = new SecretKeySpec(rawkey, "AES");
Cipher mCipher = Cipher.getInstance("AES/CFB/NoPadding");
mCipher.init(cipherMode, secretKey, new IvParameterSpec(new byte[mCipher.getBlockSize()]));
ByteBuffer byteData = ByteBuffer.allocate(1024);
while (sourceFC.read(byteData) != -1) {
// 通过通道读写交叉进行。
// 将缓冲区准备为数据传出状态
byteData.flip();
byte[] byteList = new byte[byteData.remaining()];
byteData.get(byteList, 0, byteList.length);
//此处,若不使用数组加密解密会失败,因为当byteData达不到1024个时,加密方式不同对空白字节的处理也不相同,从而导致成功与失败。
byte[] bytes = mCipher.doFinal(byteList);
targetFC.write(ByteBuffer.wrap(bytes));
byteData.clear();
}
result = true;
}catch(Exception e){
Log.e(TAG, e.getMessage(), e);
}finally{
try {
if (sourceFC != null) {
sourceFC.close();
}
if (targetFC != null) {
targetFC.close();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
}
return result;
}
/**
* 使用一个安全的随机数来产生一个密匙,密匙加密使用的
*
* @param seed
* @return
* @throws NoSuchAlgorithmException
*/
private byte[] getRawKey(byte[] seed) throws Exception {
// 获得一个随机数,传入的参数为默认方式。
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// 设置一个种子,一般是用户设定的密码
sr.setSeed(seed);
// 获得一个key生成器(AES加密模式)
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
// 设置密匙长度128位
keyGen.init(128, sr);
// 获得密匙
SecretKey key = keyGen.generateKey();
// 返回密匙的byte数组供加解密使用
byte[] raw = key.getEncoded();
return raw;
}
方式二
// AES/CBC/NoPadding no
// AES/CBC/PKCS5Padding no
// AES/CBC/ISO10126Padding no
// AES/CFB/NoPadding 无异常,但解密后的图片,打开后无内容
// AES/CFB/PKCS5Padding no
// AES/CFB/ISO10126Padding no
// AES/ECB/NoPadding no
// AES/ECB/PKCS5Padding no
// AES/ECB/ISO10126Padding no, pad block corrupted when decrypt
// AES/OFB/NoPadding 无异常,但解密后的图片,打开后无内容
// AES/OFB/PKCS5Padding no
// AES/OFB/ISO10126Padding no
// AES/PCBC/NoPadding no
// AES/PCBC/PKCS5Padding no
// AES/PCBC/ISO10126Padding no
private static final String TRANSFORMATION = "AES";
private static final String ALGORITHM = "AES";
private static final int KEY_SIZE = 128;
private static final int CACHE_SIZE = 1024;
public static void encryptFile(String sourceFilePath, String destFilePath) throws Exception{
File sourceFile = new File(sourceFilePath);
File destFile = new File(destFilePath);
destFile.createNewFile();
InputStream is = null;
OutputStream os = null;
CipherInputStream cis = null;
is = new FileInputStream(sourceFile);
os = new FileOutputStream(destFile);
// key
String seed = "abc";
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(seed.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
// kgen.init(KEY_SIZE);
kgen.init(KEY_SIZE, sr);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);
// Cipher
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
cis = new CipherInputStream(is, cipher);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = cis.read(cache)) != -1) {
os.write(cache, 0, nRead);
os.flush();
}
os.close();
cis.close();
is.close();
}
public static void decryptFile(String sourceFilePath, String destFilePath) throws Exception{
File sourceFile = new File(sourceFilePath);
File destFile = new File(destFilePath);
destFile.createNewFile();
InputStream is = null;
OutputStream os = null;
CipherOutputStream cos = null;
is = new FileInputStream(sourceFile);
os = new FileOutputStream(destFile);
// key
String seed = "abc";
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(seed.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
// kgen.init(KEY_SIZE);
kgen.init(KEY_SIZE, sr);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
cos = new CipherOutputStream(os, cipher);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = is.read(cache)) != -1) {
cos.write(cache, 0, nRead);
cos.flush();
}
cos.close();
os.close();
is.close();
}
方式三
private static final int CACHE_SIZE = 1024;
public static void encryptFile(String sourceFilePath, String destFilePath) throws Exception{
File sourceFile = new File(sourceFilePath);
File destFile = new File(destFilePath);
destFile.createNewFile();
InputStream is = new FileInputStream(sourceFile);
OutputStream os = new FileOutputStream(destFile);
int seed = 1;
os.write(seed);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = is.read(cache)) != -1) {
os.write(cache, 0, nRead);
os.flush();
}
os.close();
is.close();
}
public static void decryptFile(String sourceFilePath, String destFilePath) throws Exception{
File sourceFile = new File(sourceFilePath);
File destFile = new File(destFilePath);
destFile.createNewFile();
InputStream is = new FileInputStream(sourceFile);
OutputStream os = new FileOutputStream(destFile);
int seed = is.read();
Log.d(TAG, "seed: " + seed);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = is.read(cache)) != -1) {
os.write(cache, 0, nRead);
os.flush();
}
os.close();
is.close();
}
方式四
public static void encryptFile(String sourceFilePath) throws Exception{
RandomAccessFile file = new RandomAccessFile(sourceFilePath, "rw");
file.seek(0);
byte first = file.readByte();
byte second = file.readByte();
file.seek(0);
file.writeByte(second);
file.writeByte(first);
file.close();
}
注:部分代码源于网络,但已记不清源自哪里。