999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

實現Javascript-Delphi高強度加密傳輸安全

2018-02-05 09:16:58曾程勝
軟件 2018年1期

曾程勝

(江西省撫州市臨川區政務信息化工作辦公室,江西 撫州 344000)

1 設計思想

為了保證應用前端向后端傳輸數據的安全,我們通常采用SSL加密方式,本文是在通常HTTP上實現前臺Javascript向后臺Delphi開發的服務器端傳輸數據的加密[1],防止由于第三方攻擊導致重要信息泄露。由于RSA加密[2]對明文字符長度有限制,所以設計思想是:客戶端首先向服務器端發出AJAX請求,獲取后臺隨機生的RSA加密算法的公鑰,然后客戶端隨機生成 AES對稱加密算法[3]的Key及 iv向量,當客戶端提交表單數據時,利用AES加密表單數據,再用RSA公鑰加密AES的Key、iv向量,并以jQuery POST[4]方式向后臺提交這些加密數據,最后在后臺使用RSA私鑰解密Key、iv,從而解密表單數據。

2 Web前端的實現。

前端使用了JAVASCRIPT加密庫FORGE[5],下載地址 https://github.com/digitalbazaar/forge以及forge瀏覽器支持庫 https://github.com/digitalbazaar/forge-dist,具體實現代碼如下:

//引入JS庫

3 后端的實現

下面我將分別探討使用 OPENSSL[6]動態鏈接庫及商用組件SecureBlackbox[7]實現后端處理。我這里服務器端開發采用 IIS[8]+RealThinClient[9]+ISAPI[10]方式,僅供參考。

3.1 使用OPENSSL動態鏈接庫實現后端

由于直接使用openssl動態鏈接庫不是很方便,我借助開源組件 ICS[11]進行開發,該組件完整實現了對 OPENSSL的封裝,下載地址為 http://wiki.overbyte.eu/arch/icsv8w.zip。該方案優點是性能好,處理速度快,缺點是部署時須附帶 OPENSSL動態鏈接庫。

uses

System.SysUtils, System.Classes, rtcConn,rtcDataSrv, rtcISAPISrv, rtcInfo,

rtcSys

tem,OverbyteIcsSSLEAY,OverbyteIcsMimeUtils,Over byteIcsWSocket,

Over

byteIcsSslX509Utils,OverbyteIcsLibeay,OverByteIcs MD5,OverbyteIcsTypes,

OverbyteIcsLogger,OverbyteIcsUtils;

type

TWebModule = class(TDataModule)

GetPubKey: TRtcDataProvider;

PrdWebServer: TRtcISAPIServer;

SendEncTxt: TRtcDataProvider;

procedure GetPubKeyCheckRequest(Sender:TRtcConnection);

procedure SendEncTxtCheckRequest(Sender: TRtcConnection);

procedure SendEncTxtDataReceived(Sender:TRtcConnection);

procedure DataModuleCreate(Sender: Tobject);

procedure DataModuleDestroy(Sender: Tobject);

private

{ Private declarations }

FProgDir:string;

FSslCertTools: TSslCertTools;

public

{ Public declarations }

end;

const

AES_BLOCK_SIZE = 16;

type

TAesType = (aesCbc, aesEcb);

TAesContext = packed record

Ctx : PEVP_CIPHER_CTX;

Aes : PEVP_CIPHER;

Encrypt : Boolean;//True為加密False為解密

end;

PAesContext = ^TAesContext;

function StrToHex(AStr: AnsiString): AnsiString;

var

len : Integer;

begin

len:=Length(AStr);

SetLength(Result, len*2);

BinToHex(@AStr[1], PAnsiChar(Result), len);

Result:=string.LowerCase(Result);

end;

function HexToStr(AHex: AnsiString): AnsiS-

tring;

var

len : Integer;

begin

len:=Length(AHex)div 2;

SetLength(Result, len);

HexToBin(PAnsiChar(AHex),Result[1] , len);

end;

procedure AesFinalize(var AesCtx: TAesContext);

begin

if Assigned(AesCtx.Ctx) then begin

f_EVP_CIPHER_CTX_cleanup(AesCtx.Ctx);

f_EVP_CIPHER_CTX_free(AesCtx.Ctx);

end;

FillChar(AesCtx, SizeOf(AesCtx), #0);

end;

procedure AesInitialize(

var AesCtx : TAesContext;

Key : PAnsiChar; // if not nil Pwd is ignored and the user is responsible to provide a valid Key and IV

IV : PAnsiChar;

AesType : TAesType;

Enc : Boolean);

begin

AesFinalize(AesCtx);

AesCtx.Encrypt := Enc;

case AesType of

aesCbc, aesEcb :

begin

if AesType = aesCbc then

AesCtx.Aes := f_EVP_aes_256_cbc//CBC加密方式

else begin

AesCtx.Aes := f_EVP_aes_256_ecb;//ECB加密

end;

end;

else

raise Exception.Create('Not implemented');

end;

AesCtx.Ctx := f_EVP_CIPHER_CTX_new;

if ICS_OPENSSL_VERSION_NUMBER

f_EVP_CIPHER_CTX_init(AesCtx.Ctx)

else

f_EVP_CIPHER_CTX_reset(AesCtx.Ctx);

if not f_EVP_CipherInit_ex(AesCtx.Ctx,AesCtx.Aes, nil,

@key[0],

@IV[0],

Ord(Enc)) then

raise Exception.Create('Function f_EVP_CipherInit_ex');

end;

procedure AesUpdate(

const InBuf;

InLen : Integer;

const OutBuf;

var OutLen : Integer;

AesCtx : TAesContext);

begin

if not Assigned(AesCtx.Ctx) then

raise Exception.Create('Aes context not initialized');

if not f_EVP_CipherUpdate(AesCtx.Ctx,PAnsiChar(@OutBuf), OutLen,

AnsiChar(@InBuf),InLen) then

raise Exception.Create('f_EVP_Cipher-Update')

end;

procedure AesFinal(

const OutBuf;

var OutLen : Integer;

AesCtx : TAesContext);

begin

if not Assigned(AesCtx.Ctx) then

raise Exception.Create('Aes context not initialized');

if not f_EVP_CipherFinal_ex(AesCtx.Ctx,

PAnsiChar(@OutBuf), OutLen) then raise Exception.Create('Function f_

EVP_CipherFinal_ex:');

end;

{ Takes plain text, returns an encrypted string,optionally base64 encoded }

function StrEncAES(

const S : AnsiString;

Key : PAnsiChar;

IV : PAnsiChar;

B64 : Boolean): AnsiString;

var

Len, TmpLen : Integer;

AesCtx : TAesContext;

begin

FillChar(AesCtx, SizeOf(AesCtx), #0);

AesInitialize(AesCtx, Key, IV, aesCbc, True);

try

Len := Length(S);

SetLength(Result, Len + AES_BLOCK_SIZE);

AesUpdate(S[1], Length(S), Result[1],Len, AesCtx);

AesFinal(Result[Len + 1], TmpLen,AesCtx);

Inc(Len, TmpLen);

SetLength(Result, Len);

finally

AesFinalize(AesCtx);

end;

if B64 then

Result := Base64Encode(Result)

else

Result := StrToHex(Result)

end;

function StrDecAES(

S : AnsiString;

Key : PAnsiChar;

IV : PAnsiChar;

B64 : Boolean): AnsiString;

var

Len, TmpLen : Integer;

AesCtx : TAesContext;

begin

FillChar(AesCtx, SizeOf(AesCtx), #0);

AesInitialize(AesCtx, Key, IV, aesCbc,False);

try

if B64 then

S := Base64Decode(S);

Len := Length(S);

SetLength(Result, Len + AES_BLOCK_SIZE);

AesUpdate(S[1], Length(S), Result[1],Len, AesCtx);

AesFinal(Result[Len + 1], TmpLen,

AesCtx);

Inc(Len, TmpLen);

SetLength(Result, Len);finally AesFinalize(AesCtx);

end;end;

procedure TWebModule.DataModuleCreate(Sender: TObject);

begin

//掛載OPENSSL的動態鏈接庫,這里須將動態鏈接庫拷貝至運行目錄下

FProgDir := ExtractFilePath(ParamStr(0));

GSSLEAY_DLL_IgnoreNew := False; { V8.38 don't ignore OpenSSL 1.1.0 and later }

//GSSLEAY_DLL_IgnoreNew := True; { V8.38 don't ignore OpenSSL 1.1.0 and later }

//GSSLEAY_DLL_IgnoreOld := True; { V8.38 ignore OpenSSL 1.0.2 and earlier }

GSSL_DLL_DIR := FProgDir; { V8.38 only from our directory }

//GSSL_SignTest_Check := True; { V8.38 check digitally signed }

//GSSL_SignTest_Certificate := True; { V8.38 check digital certificate }

OverbyteIcsWSocket.LoadSsl;

FSslCertTools := TSslCertTools.Create(self);

//TSslPrivKeyType(0),0--1024位,1--2048 2--3072 3--4096 4--7680 5--15360

FSslCertTools.PrivKeyType :=TSslPrivKeyType(1);//2048位足夠安全,過高將嚴重影響性能

FSslCertTools.DoKeyPair;//隨機產生 RSA公鑰及私鑰

end;

procedure TWebModule.DataModuleDestroy(Sender: TObject);

begin

FreeAndNil(FSslCertTools);

end;

//允許請求獲取公鑰

procedure TWebModule.GetPubKeyCheckRequest(Sender: TRtcConnection);

begin

with Sender as TRtcDataServer do

if UpperCase(Request.FileName)='/GETPUBKEY' then

Accept;

end;

//將公鑰發至前端

procedure TWebModule.GetPubKeyDataReceived(Sender: TRtcConnection);

var

ABio: PBIO;

Len: Integer;

PubKey:string;

t:TRtcRecord;

begin

with Sender as TRtcDataServer do

if Request.Complete then

begin

ABio := f_BIO_new(f_BIO_s_mem);//建立內存流

f_PEM_write_bio_PUBKEY(ABio,

FSslCertTools.PrivateKey);//把從私鑰中導出公鑰并寫入內存流

Len := f_BIO_ctrl(ABio, BIO_CTRL_PENDING, 0, nil);

PubKey := String(FSslCertTools.ReadStr-Bio(ABio, Len));{ V8.41 }

f_bio_free(ABio);//釋放內存流

Re

sponse.ContentType:='application/json';

t:=TRtcRecord.Create;

t.asText['pubkey']:=PubKey;

Write(t.toJSON);

t.Free;

end;

end;

procedure TWebModule.SendEncTxtCheckRequest(Sender: TRtcConnection);

begin

with Sender as TRtcDataServer do

if UpperCase(Request.FileName)='/SENDENCTXT' then

Accept;

end;

procedure TWebModule.SendEncTxtDataReceived(Sender: TRtcConnection);

var

CipherText:AnsiString;

Key:AnsiString;

IV:AnsiString;

t:TRtcRecord;

begin

with Sender as TRtcDataServer do

if Request.Complete then

begin

Request.Params.AddText(Read);

Key:=AnsiString(StrDecRsa(FSslCertTools.Priva teKey, AnsiString(TNetEncoding.URL.Decode(Request.Params['key'])),True));

IV:=AnsiString(StrDecRsa(FSslCertTools.PrivateKey, AnsiString(TNetEncoding.URL.Decode(Request.Params['iv'])),True));

CipherText:=AnsiString(Request.Params['encrypted']);

Response.ContentType:='application/json';

t:=TRtcRecord.Create;

//將解密的字符發送至前端進行驗證

t.asText['str']:=StrDecAES(HexToStr(CipherText),PAnsiChar(HexToStr(Key)),PAnsiChar(HexToStr(IV)),False);

Write(t.toJSON);

t.Free;

end;

end;

3.2 使用SecureBlackbox組件實現

此方案優點是部署無須附帶額外文件,缺點就是處理速度稍慢,并且此組件正版費用較高。

uses

System.SysUtils, System.Classes, rtcConn,rtcDataSrv, rtcISAPISrv, rtcInfo,

rtcSystem,SBTypes, SBUtils, SBSymmetric-Crypto, SBConstants, SBHashFunction,

SBEncoding, SBRandom, SBPublicKeyCrypto,SBX509,System.NetEncoding;

type

TWebModule = class(TDataModule)

GetPubKey: TRtcDataProvider;

PrdWebServer: TRtcISAPIServer;

SendEncTxt: TRtcDataProvider;

procedure GetPubKeyCheckRequest(Sender:TRtcConnection);

procedure GetPubKeyDataReceived(Sender:TRtcConnection);

procedure SendEncTxtCheckRequest(Sender: TRtcConnection);

procedure SendEncTxtDataReceived(Sender:TRtcConnection);

procedure DataModuleCreate(Sender: TObject);

procedure DataModuleDestroy(Sender: Tobject);

private

{ Private declarations }

FFactory : TElSymmetricCryptoFactory;

RSAKeyMaterial: TElRSAKeyMaterial;

RSACrypto : TElRSAPublicKeyCrypto;

function CreateKeyMaterial(AESKey:AnsiString;AESIV:AnsiString): TelSymmetricKeyMaterial;

public

{ Public declarations }end;

function TWebModule.CreateKeyMaterial(AESKey:AnsiString;AESIV:AnsiString): TelSymmetricKeyMaterial;

var

IV, Key : ByteArray;

Size : integer;

begin

if (Length(AESKey) <> 256 div 4) or(Length(AESIV) <> 128 div 4) then

raise Exception.Create('Empty or invalid Key/IV value!');

SetLength(IV, 16);

Size := 16;

SBUtils.StringToBinary(AESIV, @IV[0], Size);

SetLength(IV, Size);

SetLength(Key, 32);

Size := 32;

SBUtils.StringToBinary(AESKey, @Key[0], Size);

SetLength(Key, Size);

Result := TElSymmetricKeyMaterial.Create;

Result.Key := Key;

Result.IV := IV;

end;

procedure TWebModule.DataModuleCreate(Sender: TObject);

begin

FFactory := TElSymmetricCryptoFactory.Create;

RSAKeyMaterial := TElRSAKeyMaterial.Create;

RSAKeyMaterial.PEMEncode:=True;//編碼公鑰私鑰

RSAKeyMaterial.Generate(2048);//產生 2048位密鑰

RSACrypto := TElRSAPublicKeyCrypto.Create();

RSACrypto.KeyMaterial := RSAKeyMaterial;

end;

procedure TWebModule.DataModuleDestroy(Sender: TObject);

begin

FreeAndNil(FFactory);

FreeAndNil(RSAKeyMaterial);

FreeAndNil(RSACrypto);

end;

procedure TWebModule.GetPubKeyCheckRequest(Sender: TRtcConnection);

begin

with Sender as TRtcDataServer do

if UpperCase(Request.FileName)='/GETPUBKEY' then

Accept;

end;

procedure TWebModule.GetPubKeyDataReceived(Sender: TRtcConnection);

var

KeyStream:TStringStream;

t:TRtcRecord;

begin

with Sender as TRtcDataServer do

if Request.Complete then

begin

KeyStream:=TStringStream.Create;

RSAKeyMate

rial.SavePublic(KeyStream);//導出公鑰

//將生成的公鑰發送到客戶端用于加密AES KEY IV

Response.ContentType:='application/json';

t:=TRtcRecord.Create;

t.asText['pubkey']:=KeyStream.DataString;

Write(t.toJSON);

t.Free;

FreeAndNil(KeyStream);

end;

end;

procedure TWebModule.SendEncTxtCheckRequest(Sender: TRtcConnection);

begin

with Sender as TRtcDataServer do

if UpperCase(Request.FileName)='/SENDENCTXT' then

Accept;

end;

procedure TWebModule.SendEncTxtDataReceived(Sender: TRtcConnection);

var

Crypto : TElSymmetricCrypto;

KeyMaterial : TElSymmetricKeyMaterial;

InBuf, OutBuf : ByteArray;

//BufSt : AnsiString;

CipherSize:Integer;

OutSize : integer;

Key:AnsiString;

IV:AnsiString;

CipherText:AnsiString;

DecryptedStr:AnsiString;

InputStream:TStringStream;

OutputStream:TStringStream;

t:TRtcRecord;

begin

with Sender as TRtcDataServer do

if Request.Complete then

begin

Request.Params.AddText(Read);

//用RSA私鑰解密出AES的KEY IV

RSACrypto.InputEncoding := pkeBase64;//輸入流編碼方式

RSACrypto.OutputEncoding := pkeBinary;//輸出流編碼方式

InputStream:=TStringStream.Create(AnsiString(TNet-

Encoding.URL.Decode(Request.Params['key'])));

OutputStream:= TStringStream.Create;

RSACrypto.Decrypt(InputStream, OutputStream);

Key:=OutputStream.DataString;InputStream:=TStringStream.Create(AnsiString(Tnet-Encoding.URL.Decode(Request.Params['iv'])));

OutputStream:= TStringStream.Create;

RSACrypto.Decrypt(InputStream, OutputStream);

IV:=OutputStream.DataString;

FreeAndNil(InputStream);

FreeAndNil(OutputStream);

//用KEY IV解密字符串

Cipher-

Text:=AnsiString(Request.Params['encrypted']);

Crypto := FFactory.CreateInstance(SB_ALGORITHM_CNT_AES256, cmCBC);

CipherSize:=Length(CipherText) div 2;

SetLength(InBuf,CipherSize);

SBU-

tils.StringToBinary(CipherText,@InBuf[0],CipherSize);

KeyMaterial := CreateKeyMaterial(Key,IV);

Crypto.KeyMaterial := KeyMaterial;

OutSize := 0;

Crypto.Decrypt(@InBuf[0],Length(InBuf), nil, OutSize);

SetLength(OutBuf, OutSize);

Crypto.Decrypt(@InBuf[0],Length(InBuf), @OutBuf[0], OutSize);

SetLength(OutBuf, OutSize);

DecryptedStr := SBUtils.AnsiStringOf-Bytes(OutBuf);

FreeAndNil(KeyMaterial);

FreeAndNil(Crypto);

//將AES加密的字符解密后發送至客戶端進行驗證

Response.ContentType:='application/json';t:=TRtcRecord.Create;

t.asText['str']:=DecryptedStr;

Write(t.toJSON);

t.Free;

end;

end;

4 現在編譯部署后運行進行驗證:

解密的結果正確,驗證通過。

[1] 王珊珊. 計算機網絡安全防范措施探討[J]. 軟件, 2013,(8).

[2] 馬玉琢, 郭玉翠. 基于3DES和RSA的Android系統短信加密設計與實現[J], 軟件, 2016, (6).

[3] Daryl Miller, 辛磊夫. 網絡安全比加密更重要[J]. 軟件,2007, (1).

[4] Bear Bibeault, Yehuda Katz. jQuery實戰[D]. 人民郵電出版社. 2010.

[5] GitHub-digitalbazaar/forge. https://github.com/digitalbazaar/forge.

[6] openssl Cryptography and SSL/TLS Toolkit. https://www.openssl.org/.

[7] SecureBlackbox. https://www.secureblackbox. com/.

[8] Internet Information Services Development. https://msdn.microsoft.com/en-us/library/ms692515(v=vs. 90).Aspx.

[9] RTC HTTP Server in 199 lines of code. http://www. realthinclient.com/write-a-robust-cross-platform-server-in-199- lines/.

[10] ISAPI Extension Overview. https://msdn.microsoft.com/en-us/library/ms525172(v=vs. 90). Aspx.

[11] Internet Component Suite. http://wiki.overbyte.eu/wiki/index.php/Main_Page.

主站蜘蛛池模板: 国产91精品调教在线播放| 欧美人与动牲交a欧美精品| 亚洲欧美自拍视频| 国禁国产you女视频网站| 视频一区视频二区中文精品| 啪啪啪亚洲无码| 亚洲综合专区| 四虎永久在线| 白丝美女办公室高潮喷水视频| 色哟哟国产精品| 男女猛烈无遮挡午夜视频| 日韩不卡免费视频| 99re精彩视频| 日韩精品资源| 精品人妻一区二区三区蜜桃AⅤ| 亚洲视屏在线观看| 999精品在线视频| 97精品久久久大香线焦| 日韩国产综合精选| 国产一级α片| 四虎精品黑人视频| 亚洲系列中文字幕一区二区| 中文字幕日韩视频欧美一区| 狠狠亚洲婷婷综合色香| 乱人伦视频中文字幕在线| 98精品全国免费观看视频| 亚洲午夜综合网| 国产91丝袜在线观看| 不卡网亚洲无码| 青青青视频蜜桃一区二区| 少妇极品熟妇人妻专区视频| 亚洲欧美日韩久久精品| 国产亚洲欧美在线人成aaaa| 午夜a视频| 国产精品久久久精品三级| 人妻丰满熟妇αv无码| 熟女成人国产精品视频| www.精品视频| 国产精品无码一二三视频| 免费jizz在线播放| 亚洲全网成人资源在线观看| 欧美在线综合视频| 五月婷婷综合在线视频| 蜜桃臀无码内射一区二区三区| 亚洲av综合网| 高清无码不卡视频| 91久久国产热精品免费| 精品视频一区二区观看| 无码视频国产精品一区二区| 国产黄色视频综合| 五月婷婷丁香色| 精品视频91| 国产精品毛片一区| 天天色天天综合网| 久久一本日韩精品中文字幕屁孩| 亚洲AV色香蕉一区二区| 午夜无码一区二区三区| 99re经典视频在线| 综合色88| 亚洲自偷自拍另类小说| 91美女视频在线观看| 亚洲永久视频| 日本不卡在线| 重口调教一区二区视频| 一级香蕉视频在线观看| 精品三级在线| 国产自产视频一区二区三区| 欧美成人手机在线观看网址| 国产一二三区在线| 中国一级特黄视频| 中文字幕有乳无码| 日本亚洲成高清一区二区三区| 视频一区视频二区中文精品| 无码'专区第一页| 欧美在线综合视频| 久青草免费视频| 无码国产伊人| 欧美性色综合网| 免费jizz在线播放| 国产亚洲精久久久久久无码AV| 97在线免费| 成年A级毛片|