java delphi aes 加密與解密檔案相容演算法
阿新 • • 發佈:2019-02-16
本文在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的互相加解密互換。