OpenSSLでAES256暗号化するAndroidアプリケーションを作成する ~Delphiでお手軽プログラミング
Android用OpenSSLコンパイル済みライブラリのダウンロード
以下のURLなどからAndroid用OpenSSLのコンパイル済みライブラリをダウンロードしますhttps://forums.embarcadero.com/thread.jspa?messageID=824565󉓵
https://github.com/emileb/OpenSSL-for-Android-Prebuilt
ダウンロードしたZIPファイルを解凍した以下2つのファイルが必要です
libcrypto.so
libssl.so
Delphiを起動し新規プロジェクトを作成
新規作成⇒マルチデバイス アプリケーションを選択します。空のアプリケーションを選択してOKボタンをクリックします。
本ページ下部の「MamAndroidOpenSSLユニット」を MamAndroidOpenSSL.pasファイルとしてプロジェクトフォルダ内に配置します。
画面デザイン
以下のようにコンポーネントを配置ます。ソースコード
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Edit, FMX.Controls.Presentation; type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Edit1: TEdit; Edit2: TEdit; Button1: TButton; Button2: TButton; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Button3: TButton; Button4: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { private 宣言 } public { public 宣言 } end; var Form1: TForm1; const //暗号化鍵 key:string='12345678901234567890123456789012'; //CBCの時に使う初期ベクトルIV iv :string='1234567890123456'; implementation {$R *.fmx} {$R *.NmXhdpiPh.fmx ANDROID} uses MamAndroidOpenSSL; procedure TForm1.Button1Click(Sender: TObject); var keyb,decb:TBytes; enc:string; begin //Edit1.TextをAES256ECB暗号化してEdit2.Textに出力する //鍵のバイト配列を取得 keyb:=TEncoding.ASCII.GetBytes(key); //暗号化したい文字列をUTF8のバイト配列に変換 decb:=TEncoding.UTF8.GetBytes(Edit1.text); //AES256ECB暗号化してBase64エンコード MamEncAes256Ecb(decb,keyb,enc); //Edit2に暗号化したテキストを出力 Edit2.text:=enc; end; procedure TForm1.Button2Click(Sender: TObject); var keyb,decb:TBytes; begin //Edit2.TextをAES256ECB復号化してEdit1.Textに出力する //鍵のバイト配列を取得 keyb:=TEncoding.ASCII.GetBytes(key); //AES256ECB復号化 MamDecAes256Ecb(decb,keyb,Edit2.text); Edit1.Text:=TEncoding.UTF8.GetString(decb); end; procedure TForm1.Button3Click(Sender: TObject); var keyb,ivb,decb:TBytes; enc:string; begin //Edit1.TextをAES256ECB暗号化してEdit2.Textに出力する //鍵のバイト配列を取得 keyb:=TEncoding.ASCII.GetBytes(key); //初期ベクトルIVのバイト配列を取得 ivb :=TEncoding.ASCII.GetBytes(key); //暗号化したい文字列をUTF8のバイト配列に変換 decb:=TEncoding.UTF8.GetBytes(Edit1.text); //AES256CBC暗号化してBase64エンコード MamEncAes256Cbc(decb,keyb,ivb,enc); //Edit2に暗号化したテキストを出力 Edit2.text:=enc; end; procedure TForm1.Button4Click(Sender: TObject); var keyb,ivb,decb:TBytes; begin //Edit2.TextをAES256ECB復号化してEdit1.Textに出力する //鍵のバイト配列を取得 keyb:=TEncoding.ASCII.GetBytes(key); //初期ベクトルIVのバイト配列を取得 ivb :=TEncoding.ASCII.GetBytes(key); //AES256CBC復号化 MamDecAes256Cbc(decb,keyb,ivb,Edit2.text); Edit1.Text:=TEncoding.UTF8.GetString(decb); end; end.
libcrypto.soとlibssl.soの配置
プロジェクト⇒配置 をクリックします。「ファイルの追加」ボタンをクリックして「libcrypto.so」と「libssl.so」を追加します。
リモートパスを「assets\internal」に設定します。
配置でのリモートパス「assets\internal」とは内部ストレージを示し、
System.IOUtils.TPath.GetDocumentsPath()
関数で取得できるパスを示しています。
Androidのバージョンによって変わるかもしれませんが以下のディレクトリになります。
/data/user/0/[プロジェクト名]/files
配置でのリモートパス「assets」とは外部ストレージを示し、
System.IOUtils.TPath.GetSharedDocumentsPath
関数で取得できるパスを示しています。
Androidのバージョンによって変わるかもしれませんが以下のディレクトリになります。
/storage/emulated/0/Documents
openSSLライブラリのロード
プロジェクト⇒ソースの表示 をクリックします。以下の赤字の部分のように、ソースコードを修正します。
program Project1; uses System.StartUpCopy, FMX.Forms, Unit1 in 'Unit1.pas' {Form1}, MamAndroidOpenSSL in 'MamAndroidOpenSSL.pas', IdSSLOpenSSL,IdSSLOpenSSLHeaders,System.IOUtils; {$R *.res} begin IdOpenSSLSetLibPath(System.IOUtils.TPath.GetDocumentsPath); Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.
プロジェクトの実行
MamAndroidOpenSSLユニット
MamAndroidOpenSSL.pasunit MamAndroidOpenSSL; interface uses System.SysUtils,IdSSLOpenSSLHeaders,system.NetEncoding {,WinApi.Windows}; //AES-128-ECB暗号化(暗号化したいデータ,キー(16バイト) out:暗号化データ) function MamEncAes128Ecb( DecData,Key:TBytes;out EncData:TBytes):Boolean;overload; //AES-128-ECB暗号化(暗号化したいデータ,キー(16バイト) out:暗号化データのBASE64) function MamEncAes128Ecb( DecData,Key:TBytes;out EncDataBase64:String):Boolean;overload; //AES-192-ECB暗号化(暗号化したいデータ,キー(24バイト) out:暗号化データ) function MamEncAes192Ecb( DecData,Key:TBytes;out EncData:TBytes):Boolean;overload; //AES-192-ECB暗号化(暗号化したいデータ,キー(24バイト) out:暗号化データのBASE64) function MamEncAes192Ecb( DecData,Key:TBytes;out EncDataBase64:String):Boolean;overload; //AES-256-ECB暗号化(暗号化したいデータ,キー(32バイト) out:暗号化データ) function MamEncAes256Ecb( DecData,Key:TBytes;out EncData:TBytes):Boolean;overload; //AES-256-ECB暗号化(暗号化したいデータ,キー(32バイト) out:暗号化データのBASE64) function MamEncAes256Ecb( DecData,Key:TBytes;out EncDataBase64:String):Boolean;overload; //AES-128-ECB複合化(out:複合化されたデータ,キー(16バイト) ,暗号化データ) function MamDecAes128Ecb( out DecData:TBytes;Key,EncData:TBytes):Boolean;overload; //AES-128-ECB複合化(out:複合化されたデータ,キー(16バイト) ,暗号化データのBASE64) function MamDecAes128Ecb( out DecData:TBytes;Key:TBytes;EncDataBase64:String):Boolean;overload; //AES-192-ECB複合化(out:複合化されたデータ,キー(24バイト) ,暗号化データ) function MamDecAes192Ecb( out DecData:TBytes;Key,EncData:TBytes):Boolean;overload; //AES-192-ECB複合化(out:複合化されたデータ,キー(24バイト) ,暗号化データのBASE64) function MamDecAes192Ecb( out DecData:TBytes;Key:TBytes;EncDataBase64:String):Boolean;overload; //AES-256-ECB複合化(out:複合化されたデータ,キー(32バイト) ,暗号化データ) function MamDecAes256Ecb( out DecData:TBytes;Key,EncData:TBytes):Boolean;overload; //AES-256-ECB複合化(out:複合化されたデータ,キー(32バイト) ,暗号化データのBASE64) function MamDecAes256Ecb( out DecData:TBytes;Key:TBytes;EncDataBase64:String):Boolean;overload; //AES-128-CBC暗号化(暗号化したいデータ,キー(16バイト),初期ベクトル(16バイト) out:暗号化データ) function MamEncAes128Cbc( DecData,Key,Iv:TBytes;out EncData:TBytes):Boolean;overload; //AES-128-CBC暗号化(暗号化したいデータ,キー(16バイト),初期ベクトル(16バイト) out:暗号化データのBASE64) function MamEncAes128Cbc( DecData,Key,Iv:TBytes;out EncDataBase64:String):Boolean;overload; //AES-192-CBC暗号化(暗号化したいデータ,キー(24バイト),初期ベクトル(16バイト) out:暗号化データ) function MamEncAes192Cbc( DecData,Key,Iv:TBytes;out EncData:TBytes):Boolean;overload; //AES-192-CBC暗号化(暗号化したいデータ,キー(24バイト),初期ベクトル(16バイト) out:暗号化データのBASE64) function MamEncAes192Cbc( DecData,Key,Iv:TBytes;out EncDataBase64:String):Boolean;overload; //AES-256-CBC暗号化(暗号化したいデータ,キー(32バイト),初期ベクトル(16バイト) out:暗号化データ) function MamEncAes256Cbc( DecData,Key,Iv:TBytes;out EncData:TBytes):Boolean;overload; //AES-256-CBC暗号化(暗号化したいデータ,キー(32バイト),初期ベクトル(16バイト) out:暗号化データのBASE64) function MamEncAes256Cbc( DecData,Key,Iv:TBytes;out EncDataBase64:String):Boolean;overload; //AES-128-CBC複合化(out:複合化されたデータ,キー(16バイト),初期ベクトル(16バイト) ,暗号化データ) function MamDecAes128Cbc( out DecData:TBytes;Key,Iv,EncData:TBytes):Boolean;overload; //AES-128-CBC複合化(out:複合化されたデータ,キー(16バイト),初期ベクトル(16バイト) ,暗号化データのBASE64) function MamDecAes128Cbc( out DecData:TBytes;Key,Iv:TBytes;EncDataBase64:String):Boolean;overload; //AES-192-CBC複合化(out:複合化されたデータ,キー(24バイト),初期ベクトル(16バイト) ,暗号化データ) function MamDecAes192Cbc( out DecData:TBytes;Key,Iv,EncData:TBytes):Boolean;overload; //AES-192-CBC複合化(out:複合化されたデータ,キー(24バイト),初期ベクトル(16バイト) ,暗号化データのBASE64) function MamDecAes192Cbc( out DecData:TBytes;Key,Iv:TBytes;EncDataBase64:String):Boolean;overload; //AES-256-CBC複合化(out:複合化されたデータ,キー(32バイト),初期ベクトル(16バイト) ,暗号化データ) function MamDecAes256Cbc( out DecData:TBytes;Key,Iv,EncData:TBytes):Boolean;overload; //AES-256-CBC複合化(out:複合化されたデータ,キー(32バイト),初期ベクトル(16バイト) ,暗号化データのBASE64) function MamDecAes256Cbc( out DecData:TBytes;Key,Iv:TBytes;EncDataBase64:String):Boolean;overload; procedure AZeroMemory(p:Pointer;l:integer); implementation procedure AZeroMemory(p:Pointer;l:integer); var b:PByte; i:integer; begin b:=p; for i := 0 to l-1 do begin b^:=0; inc(b); end; end; function MamEncAes128Ecb( DecData,Key:TBytes;out EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Encl,Padl:integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<16 then begin l:=length(Key); SetLength(Key,16); AZeroMemory(@Key[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx,EVP_aes_128_ecb,nil,@key[0],nil); setLength(EncData, (length(DecData) div 16+1)*16); EVP_EncryptUpdate(ctx,@EncData[0],@Encl,@DecData[0],length(DecData)); EVP_EncryptFinal_ex(ctx,@EncData[Encl],@Padl); EVP_CIPHER_CTX_free(ctx); SetLength(EncData,Encl+Padl); unload; Result:=true; end; function MamEncAes128Ecb( DecData,Key:TBytes;out EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin result:=MamEncAes128Ecb(DecData,Key,EncData); EncData:=TNetEncoding.Base64.Encode(EncData); EncDataBase64:=TEncoding.ASCII.GetString(EncData); end; function MamEncAes192Ecb( DecData,Key:TBytes;out EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Encl,Padl:integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<24 then begin l:=length(Key); SetLength(Key,24); AZeroMemory(@Key[l],24-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx,EVP_aes_192_ecb,nil,@key[0],nil); setLength(EncData, (length(DecData) div 16+1)*16); EVP_EncryptUpdate(ctx,@EncData[0],@Encl,@DecData[0],length(DecData)); EVP_EncryptFinal_ex(ctx,@EncData[Encl],@Padl); EVP_CIPHER_CTX_free(ctx); SetLength(EncData,Encl+Padl); unload; Result:=true; end; function MamEncAes192Ecb( DecData,Key:TBytes;out EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin result:=MamEncAes192Ecb(DecData,Key,EncData); EncData:=TNetEncoding.Base64.Encode(EncData); EncDataBase64:=TEncoding.ASCII.GetString(EncData); end; function MamEncAes256Ecb(DecData,Key:TBytes; out EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Encl,Padl:integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<32 then begin l:=length(Key); SetLength(Key,32); AZeroMemory(@Key[l],32-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx,EVP_aes_256_ecb,nil,@key[0],nil); setLength(EncData, (length(DecData) div 16+1)*16); EVP_EncryptUpdate(ctx,@EncData[0],@Encl,@DecData[0],length(DecData)); EVP_EncryptFinal_ex(ctx,@EncData[Encl],@Padl); EVP_CIPHER_CTX_free(ctx); SetLength(EncData,Encl+Padl); unload; Result:=true; end; function MamEncAes256Ecb(DecData,Key:TBytes; out EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin result:=MamEncAes256Ecb(DecData,Key,EncData); EncData:=TNetEncoding.Base64.Encode(EncData); EncDataBase64:=TEncoding.ASCII.GetString(EncData); end; function MamDecAes128Ecb( out DecData:TBytes;Key,EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Decl,Padl:Integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<16 then begin l:=length(Key); SetLength(Key,16); AZeroMemory(@Key[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx,EVP_aes_128_ecb,nil,@key[0],nil); setLength(DecData,length(EncData)); EVP_DecryptUpdate(ctx,@DecData[0],LongWord(pointer(@Decl)), @EncData[0],Length(EncData)); EVP_DecryptFinal_ex(ctx,@DecData[Decl],LongWord(Pointer(@Padl))); setlength(DecData,Decl+Padl); unload; Result:=True; end; function MamDecAes128Ecb( out DecData:TBytes;Key:TBytes;EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin EncData:=TEncoding.ASCII.GetBytes(EncDataBase64); EncData:=TNetEncoding.Base64.Decode(EncData); Result:=MamDecAes128Ecb(DecData,Key,EncData); end; function MamDecAes192Ecb( out DecData:TBytes;Key,EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Decl,Padl:Integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<24 then begin l:=length(Key); SetLength(Key,24); AZeroMemory(@Key[l],24-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx,EVP_aes_192_ecb,nil,@key[0],nil); setLength(DecData,length(EncData)); EVP_DecryptUpdate(ctx,@DecData[0],LongWord(pointer(@Decl)), @EncData[0],Length(EncData)); EVP_DecryptFinal_ex(ctx,@DecData[Decl],LongWord(Pointer(@Padl))); setlength(DecData,Decl+Padl); unload; Result:=True; end; function MamDecAes192Ecb( out DecData:TBytes;Key:TBytes;EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin EncData:=TEncoding.ASCII.GetBytes(EncDataBase64); EncData:=TNetEncoding.Base64.Decode(EncData); Result:=MamDecAes192Ecb(DecData,Key,EncData); end; function MamDecAes256Ecb( out DecData:TBytes;Key,EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Decl,Padl:Integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<32 then begin l:=length(Key); SetLength(Key,32); AZeroMemory(@Key[l],32-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx,EVP_aes_256_ecb,nil,@key[0],nil); setLength(DecData,length(EncData)); EVP_DecryptUpdate(ctx,@DecData[0],LongWord(pointer(@Decl)), @EncData[0],Length(EncData)); EVP_DecryptFinal_ex(ctx,@DecData[Decl],LongWord(Pointer(@Padl))); setlength(DecData,Decl+Padl); unload; Result:=True; end; function MamDecAes256Ecb( out DecData:TBytes;Key:TBytes;EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin EncData:=TEncoding.ASCII.GetBytes(EncDataBase64); EncData:=TNetEncoding.Base64.Decode(EncData); Result:=MamDecAes256Ecb(DecData,Key,EncData); end; function MamEncAes128Cbc( DecData,Key,Iv:TBytes;out EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Encl,Padl:integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<16 then begin l:=length(Key); SetLength(Key,16); AZeroMemory(@Key[l],16-l); end; if length(Iv)<16 then begin l:=length(Iv); SetLength(Iv,16); AZeroMemory(@Iv[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx,EVP_aes_128_cbc,nil,@key[0],@Iv[0]); setLength(EncData, (length(DecData) div 16+1)*16); EVP_EncryptUpdate(ctx,@EncData[0],@Encl,@DecData[0],length(DecData)); EVP_EncryptFinal_ex(ctx,@EncData[Encl],@Padl); EVP_CIPHER_CTX_free(ctx); SetLength(EncData,Encl+Padl); unload; Result:=true; end; function MamEncAes128Cbc( DecData,Key,Iv:TBytes;out EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin result:=MamEncAes128Cbc(DecData,Key,Iv,EncData); EncData:=TNetEncoding.Base64.Encode(EncData); EncDataBase64:=TEncoding.ASCII.GetString(EncData); end; function MamEncAes192Cbc( DecData,Key,Iv:TBytes;out EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Encl,Padl:integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<24 then begin l:=length(Key); SetLength(Key,24); AZeroMemory(@Key[l],24-l); end; if length(Iv)<16 then begin l:=length(Iv); SetLength(Iv,16); AZeroMemory(@Iv[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx,EVP_aes_192_cbc,nil,@key[0],@Iv[0]); setLength(EncData, (length(DecData) div 16+1)*16); EVP_EncryptUpdate(ctx,@EncData[0],@Encl,@DecData[0],length(DecData)); EVP_EncryptFinal_ex(ctx,@EncData[Encl],@Padl); EVP_CIPHER_CTX_free(ctx); SetLength(EncData,Encl+Padl); unload; Result:=true; end; function MamEncAes192Cbc( DecData,Key,Iv:TBytes;out EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin result:=MamEncAes192Cbc(DecData,Key,Iv,EncData); EncData:=TNetEncoding.Base64.Encode(EncData); EncDataBase64:=TEncoding.ASCII.GetString(EncData); end; function MamEncAes256Cbc( DecData,Key,Iv:TBytes;out EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Encl,Padl:integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<32 then begin l:=length(Key); SetLength(Key,32); AZeroMemory(@Key[l],32-l); end; if length(Iv)<16 then begin l:=length(Iv); SetLength(Iv,16); AZeroMemory(@Iv[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx,EVP_aes_256_cbc,nil,@key[0],@Iv[0]); setLength(EncData, (length(DecData) div 16+1)*16); EVP_EncryptUpdate(ctx,@EncData[0],@Encl,@DecData[0],length(DecData)); EVP_EncryptFinal_ex(ctx,@EncData[Encl],@Padl); EVP_CIPHER_CTX_free(ctx); SetLength(EncData,Encl+Padl); unload; Result:=true; end; function MamEncAes256Cbc( DecData,Key,Iv:TBytes;out EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin result:=MamEncAes256Cbc(DecData,Key,Iv,EncData); EncData:=TNetEncoding.Base64.Encode(EncData); EncDataBase64:=TEncoding.ASCII.GetString(EncData); end; function MamDecAes128Cbc( out DecData:TBytes;Key,Iv,EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Decl,Padl:Integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<16 then begin l:=length(Key); SetLength(Key,16); AZeroMemory(@Key[l],16-l); end; if length(Iv)<16 then begin l:=length(Iv); SetLength(Iv,16); AZeroMemory(@Iv[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx,EVP_aes_128_cbc,nil,@key[0],@Iv[0]); setLength(DecData,length(EncData)); EVP_DecryptUpdate(ctx,@DecData[0],LongWord(pointer(@Decl)), @EncData[0],Length(EncData)); EVP_DecryptFinal_ex(ctx,@DecData[Decl],LongWord(Pointer(@Padl))); setlength(DecData,Decl+Padl); unload; Result:=True; end; function MamDecAes128Cbc( out DecData:TBytes;Key,Iv:TBytes;EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin EncData:=TEncoding.ASCII.GetBytes(EncDataBase64); EncData:=TNetEncoding.Base64.Decode(EncData); Result:=MamDecAes128Cbc(DecData,Key,Iv,EncData); end; function MamDecAes192Cbc( out DecData:TBytes;Key,Iv,EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Decl,Padl:Integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<24 then begin l:=length(Key); SetLength(Key,24); AZeroMemory(@Key[l],24-l); end; if length(Iv)<16 then begin l:=length(Iv); SetLength(Iv,16); AZeroMemory(@Iv[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx,EVP_aes_192_cbc,nil,@key[0],@Iv[0]); setLength(DecData,length(EncData)); EVP_DecryptUpdate(ctx,@DecData[0],LongWord(pointer(@Decl)), @EncData[0],Length(EncData)); EVP_DecryptFinal_ex(ctx,@DecData[Decl],LongWord(Pointer(@Padl))); setlength(DecData,Decl+Padl); unload; Result:=True; end; function MamDecAes192Cbc( out DecData:TBytes;Key,Iv:TBytes;EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin EncData:=TEncoding.ASCII.GetBytes(EncDataBase64); EncData:=TNetEncoding.Base64.Decode(EncData); Result:=MamDecAes192Cbc(DecData,Key,Iv,EncData); end; function MamDecAes256Cbc( out DecData:TBytes;Key,Iv,EncData:TBytes):Boolean;overload; var ctx:PEVP_CIPHER_CTX; Decl,Padl:Integer; l:integer; begin Result:=false; if not load then exit; if length(Key)<32 then begin l:=length(Key); SetLength(Key,32); AZeroMemory(@Key[l],32-l); end; if length(Iv)<16 then begin l:=length(Iv); SetLength(Iv,16); AZeroMemory(@Iv[l],16-l); end; ctx:=EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_DecryptInit_ex(ctx,EVP_aes_256_cbc,nil,@key[0],@Iv[0]); setLength(DecData,length(EncData)); EVP_DecryptUpdate(ctx,@DecData[0],LongWord(pointer(@Decl)), @EncData[0],Length(EncData)); EVP_DecryptFinal_ex(ctx,@DecData[Decl],LongWord(Pointer(@Padl))); setlength(DecData,Decl+Padl); unload; Result:=True; end; function MamDecAes256Cbc( out DecData:TBytes;Key,Iv:TBytes;EncDataBase64:String):Boolean;overload; var EncData:TBytes; begin EncData:=TEncoding.ASCII.GetBytes(EncDataBase64); EncData:=TNetEncoding.Base64.Decode(EncData); Result:=MamDecAes256Cbc(DecData,Key,Iv,EncData); end; end.