1. 程式人生 > >java delphi aes 加密與解密檔案相容演算法

java delphi aes 加密與解密檔案相容演算法

本文在oracle jdk 1.8, delphi xe3下面測試加密與解密模式都成功通過。

java端加密與解密演算法程式碼

package com.shit;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil {

	private static final byte[] PASSWORD=new byte[] { 't', 'e', 's', 't', '_', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd','1', '2', '3' }; 
	
	public static byte[] encrypt(byte[] Data) throws Exception {
		Key key = new SecretKeySpec(PASSWORD, "AES");
		// Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte[] encVal = cipher.doFinal(Data);
		return encVal;
	}

	public static byte[] decrypt(byte[] encryptedData) throws Exception {
		Key key = new SecretKeySpec(PASSWORD, "AES");
		 Cipher chiper = Cipher.getInstance("AES");
		 chiper.init(Cipher.DECRYPT_MODE, key);
		byte[] decValue = chiper.doFinal(encryptedData);
		return decValue;
	}

	public static void encodeFile(String sourceFile,String outputFile) throws Exception {
		File file = new File(sourceFile);
		FileInputStream in = new FileInputStream(file);
		try{
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			byte[] tmpbuf = new byte[1024];
			int count = 0;
			while ((count = in.read(tmpbuf)) != -1) {
				bout.write(tmpbuf, 0, count);
				tmpbuf = new byte[1024];
			}
			byte[] orgData = bout.toByteArray();
			byte[] raw = encrypt(orgData);
			file = new File(outputFile);
			FileOutputStream out=null;
			try {
				out= new FileOutputStream(file);
				out.write(raw);
			} finally {
				out.close();
			}
		}finally{
			in.close();
		}
	}

	public static void decodeFile(String sourceFile,String outputFile) throws Exception{
		File file = new File(sourceFile);
		FileInputStream fis = new FileInputStream(file);
		try {
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			byte[] tmpbuf = new byte[1024];
			int count = 0;
			while ((count = fis.read(tmpbuf)) != -1) {
				bout.write(tmpbuf, 0, count);
				tmpbuf = new byte[1024];
			}
			byte[] orgData = bout.toByteArray();
			byte[] raws = decrypt(orgData);

			file = new File(outputFile);
			FileOutputStream fos = null;
			try {
				fos = new FileOutputStream(file);
				fos.write(raws);
			} finally {
				fos.close();
			}
		} finally {
			fis.close();
		}
	}

	public static void main(String[] args) {
		String input_file="d:/1.jpg";
		String output_file="d:/1_encrypted.jpg";
		String after_decrypt_file="d:/2.jpg";
		try {
			encodeFile(input_file,output_file);
			decodeFile(output_file,after_decrypt_file);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}
}

delphi xe3這邊的加密及解密關鍵程式碼
function download_file_to_stream(const url: string; outputStream: TMemoryStream): TMemoryStream;
var
  h: TIdhttp;
begin
  h := Tidhttp.Create(nil);
  try
    try
      h.get(url, outputStream);
    except
    end;
    result := outputStream;
  finally
    h.Free;
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  http_download_stream: TMemoryStream;
  output_stream: TMemoryStream;
  password:String;
begin
  password:='test_password123';
  http_download_stream := TMemoryStream.Create;
  output_stream := TMemoryStream.Create;
  try
    http_download_stream := download_file_to_stream('http://localhost:8080/docs/1_encrypted.jpg', http_download_stream);
    http_download_stream.Position := 0;
    output_stream := DecryptStream(http_download_stream, output_stream,password) as TMemoryStream;
    output_stream.Position := 0;
    output_stream.SaveToFile('d:/1_de.jpg');
  finally
    http_download_stream.Free;
    output_stream.Free;
  end;
end;

delphi這一邊的aes演算法我測試過dcrypt2,lockbox,cryptobboxvcl等這些,結論就是以上這幾個全都不能用,java裡面預設的aes加密實現是128bit的AES/ECB/PKCS5Padding這種模式的,在預設加密模式下面涉及不到IV向量這些東西,就直接Cipher.getInstance("AES");就是AES/ECB/PKCS5Padding這種加密模式了,delphi這一邊最終還是通過AES.pas和EIAES.pas這兩個元件實現的,但是我下載到的原始碼有問題,無法完成與java之間的直接互相加解密轉換,對於該程式碼進行了一定的修改以後才最終可以實現與java的互相加解密互換。