mainform.pas
来自「著名的SecureBlackBox控件完整源码」· PAS 代码 · 共 860 行 · 第 1/2 页
PAS
860 行
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls, ComCtrls,
{$ifdef DELPHI_NET}
System.IO,
System.ComponentModel,
{$endif}
EncForm,
SBUtils, SBConstants, SBAES, SB3DES, SBDES, SBCamellia, SBRC4, SBX509,
SBPublicKeyCrypto, SBPGPKeys,
SBXMLCore, SBXMLDefs, SBXMLEnc, SBXMLSec, SBXMLCharsets;
type
TfrmMain = class(TForm)
edXMLFile: TEdit;
btnLoadXML: TButton;
lbXMLFile: TLabel;
sbBrowseXMLFile: TSpeedButton;
btnSaveXML: TButton;
dlgOpenXML: TOpenDialog;
tvXML: TTreeView;
btnEncrypt: TButton;
btnDecrypt: TButton;
mmXML: TMemo;
btnClear: TButton;
lbNodeType: TLabel;
dlbNodeType: TLabel;
btnDelete: TButton;
lbNamespaceURI: TLabel;
dlbNamespaceURI: TLabel;
procedure btnDecryptClick(Sender: TObject);
procedure btnDeleteClick(Sender: TObject);
procedure btnSaveXMLClick(Sender: TObject);
procedure btnClearClick(Sender: TObject);
procedure btnEncryptClick(Sender: TObject);
procedure tvXMLChange(Sender: TObject; Node: TTreeNode);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnLoadXMLClick(Sender: TObject);
procedure sbBrowseXMLFileClick(Sender: TObject);
private
FXMLDocument: TElXMLDOMDocument;
public
procedure LoadCertificate(F: {$ifndef DELPHI_NET}TFileStream{$else}FileStream{$endif};
const Password: string; X509KeyData: TElXMLKeyInfoX509Data);
procedure UpdateXML;
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.btnClearClick(Sender: TObject);
begin
FreeAndNil(FXMLDocument);
FXMLDocument := TElXMLDOMDocument.Create;
UpdateXML;
end;
procedure TfrmMain.btnDecryptClick(Sender: TObject);
var
Decryptor: TElXMLDecryptor;
SymKeyData, SymKEKData: TElXMLKeyInfoSymmetricData;
RSAKeyData: TElXMLKeyInfoRSAData;
X509KeyData: TElXMLKeyInfoX509Data;
{$ifndef SBB_EXCL_XML_PGP}
PGPKeyData: TElXMLKeyInfoPGPData;
{$endif}
F: {$ifndef DELPHI_NET}TFileStream{$else}FileStream{$endif};
Node, T: TElXMLDOMNode;
i: Integer;
begin
if Assigned(tvXML.Selected) and
Assigned(tvXML.Selected.Data) then
Node := TElXMLDOMNode(tvXML.Selected.Data)
else
Node := TElXMLDOMNode(FXMLDocument);
while (Node is TElXMLDOMElement) and
(TElXMLDOMElement(Node).LocalName <> 'EncryptedData') and
Assigned(Node.ParentNode) do
Node := Node.ParentNode;
if (Node is TElXMLDOMElement) and
(TElXMLDOMElement(Node).LocalName = 'EncryptedData') and
Assigned(Node.ParentNode) and
(Node.ParentNode is TElXMLDOMDocument) then
Node := Node.ParentNode;
if Node is TElXMLDOMDocument then
T := Node.FirstChild
else
T := Node;
if (not (T is TElXMLDOMElement) or
(TElXMLDOMElement(T).LocalName <> 'EncryptedData')) then
begin
MessageDlg('Please, select EncryptedData element or Document for decryption.', mtInformation, [mbOK], 0);
Exit;
end;
SymKeyData := nil;
SymKEKData := nil;
RSAKeyData := nil;
X509KeyData := nil;
{$ifndef SBB_EXCL_XML_PGP}
PGPKeyData := nil;
{$endif}
Decryptor := TElXMLDecryptor.Create(Self);
try
try
if Node is TElXMLDOMDocument then
Decryptor.Load(TElXMLDOMDocument(Node))
else
Decryptor.Load(TElXMLDOMElement(Node));
except
on E: Exception do
raise EXMLError.CreateFmt('Encrypted data loading failed. (%s)', [E.Message]);
end;
frmEnc.EncryptKey := Decryptor.EncryptKey;
frmEnc.EncryptedDataType := Decryptor.EncryptedDataType;
frmEnc.EncryptionMethod := Decryptor.EncryptionMethod;
frmEnc.KeyEncryptionType := Decryptor.KeyEncryptionType;
frmEnc.KeyTransportMethod := Decryptor.KeyTransportMethod;
frmEnc.KeyWrapMethod := Decryptor.KeyWrapMethod;
frmEnc.KeyName := Decryptor.KeyName;
frmEnc.MimeType := Decryptor.MimeType;
frmEnc.LockOpt := True;
frmEnc.UpdateOpt;
while True do
begin
if frmEnc.ShowModal = mrOK then
begin
if Decryptor.EncryptKey then
begin
if Decryptor.KeyEncryptionType = xetKeyWrap then
begin
SymKEKData := TElXMLKeyInfoSymmetricData.Create(True);
{$ifndef DELPHI_NET}
F := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
{$else}
F := FileStream.Create(frmEnc.KeyFile, FileMode.Open, FileAccess.Read);
{$endif}
try
SymKEKData.Key.Load(F);
finally
FreeAndNil(F);
end;
Decryptor.KeyEncryptionKeyData := SymKEKData;
end
else
begin
FreeAndNil(RSAKeyData);
FreeAndNil(X509KeyData);
{$ifndef SBB_EXCL_XML_PGP}
FreeAndNil(PGPKeyData);
{$endif}
RSAKeyData := TElXMLKeyInfoRSAData.Create(True);
RSAKeyData.RSAKeyMaterial.Passphrase := frmEnc.Passphrase;
X509KeyData := TElXMLKeyInfoX509Data.Create(True);
{$ifndef SBB_EXCL_XML_PGP}
PGPKeyData := TElXMLKeyInfoPGPData.Create(True);
{$endif}
{$ifndef DELPHI_NET}
F := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
{$else}
F := FileStream.Create(frmEnc.KeyFile, FileMode.Open, FileAccess.Read);
{$endif}
try
RSAKeyData.RSAKeyMaterial.LoadSecret(F);
except
end;
if not RSAKeyData.RSAKeyMaterial.SecretKey then
begin
F.Position := 0;
LoadCertificate(F, frmEnc.Passphrase, X509KeyData);
end;
{$ifndef SBB_EXCL_XML_PGP}
if not RSAKeyData.RSAKeyMaterial.PublicKey and
not Assigned(X509KeyData.Certificate) then
begin
F.Position := 0;
PGPKeyData.SecretKey := TElPGPSecretKey.Create;
PGPKeyData.SecretKey.Passphrase := frmEnc.Passphrase;
try
PGPKeyData.SecretKey.LoadFromStream(F);
except
PGPKeyData.SecretKey.Free;
PGPKeyData.SecretKey := nil;
end;
end;
{$endif}
FreeAndNil(F);
if RSAKeyData.RSAKeyMaterial.SecretKey then
Decryptor.KeyEncryptionKeyData := RSAKeyData
else
if Assigned(X509KeyData.Certificate) then
Decryptor.KeyEncryptionKeyData := X509KeyData
{$ifndef SBB_EXCL_XML_PGP}
else
if Assigned(PGPKeyData.SecretKey) then
Decryptor.KeyEncryptionKeyData := PGPKeyData
{$endif}
else
raise EXMLError.Create('Key not loaded.');
end;
end
else
begin
SymKeyData := TElXMLKeyInfoSymmetricData.Create(True);
{$ifndef DELPHI_NET}
F := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
{$else}
F := FileStream.Create(frmEnc.KeyFile, FileMode.Open, FileAccess.Read);
{$endif}
try
SymKeyData.Key.Load(F);
finally
FreeAndNil(F);
end;
Decryptor.KeyData := SymKeyData;
end;
i := Decryptor.Decrypt(FXMLDocument);
if i <> SB_XML_ENC_ERROR_OK then
begin
if (not Decryptor.EncryptKey and (i = SB_XML_ENC_ERROR_INVALID_KEY)) or
(Decryptor.EncryptKey and (i = SB_XML_ENC_ERROR_INVALID_KEK)) then
MessageDlg('Decryption failed. Bad key or data is corrupted.', mtError, [mbOK], 0)
else
raise EXMLEncError.CreateFmt('Decryption failed. Error code: 0x%x', [i]);
Continue;
end;
if Decryptor.EncryptedDataType = xedtExternal then
begin
{$ifndef DELPHI_NET}
F := TFileStream.Create(frmEnc.ExternalFile, fmCreate);
{$else}
F := FileStream.Create(frmEnc.ExternalFile, FileMode.Create, FileAccess.ReadWrite);
{$endif}
try
if Length(Decryptor.DecryptedData) > 0 then
{$ifndef DELPHI_NET}
F.Write(Decryptor.DecryptedData[0], Length(Decryptor.DecryptedData));
{$else}
F.Write(Decryptor.DecryptedData, 0, Length(Decryptor.DecryptedData));
{$endif}
finally
FreeAndNil(F);
end;
MessageDlg('Data saved successfully.', mtInformation, [mbOK], 0);
end
else
begin
if Assigned(Decryptor.DecryptedNode) then
begin
if Node is TElXMLDOMDocument then
FXMLDocument.ReplaceChild(Decryptor.DecryptedNode, FXMLDocument.FirstChild)
else
Node.ParentNode.ReplaceChild(Decryptor.DecryptedNode, Node);
Decryptor.DecryptedNode := nil;
end
else
if (Decryptor.EncryptedDataType = xedtContent) and
Assigned(Decryptor.DecryptedNodeList) then
begin
T := Node.ParentNode;
for i := 0 to Decryptor.DecryptedNodeList.Length - 1 do
T.InsertBefore(Decryptor.DecryptedNodeList.Item[i].CloneNode(True), Node);
T.RemoveChild(Node);
end;
UpdateXML;
end;
Break;
end
else
Break;
end;
finally
FreeAndNil(Decryptor);
FreeAndNil(SymKeyData);
FreeAndNil(SymKEKData);
FreeAndNil(RSAKeyData);
FreeAndNil(X509KeyData);
{$ifndef SBB_EXCL_XML_PGP}
FreeAndNil(PGPKeyData);
{$endif}
end;
end;
procedure TfrmMain.btnDeleteClick(Sender: TObject);
var
N: TElXMLDOMNode;
begin
if Assigned(tvXML.Selected) and
Assigned(tvXML.Selected.Data) then
begin
N := TElXMLDOMNode(tvXML.Selected.Data);
if (N is TElXMLDOMElement) or
(N is TElXMLDOMText) then
begin
if Assigned(N.ParentNode) then
N.ParentNode.RemoveChild(N)
else
FXMLDocument.RemoveChild(N);
end
else
if (N is TElXMLDOMAttr) and Assigned(tvXML.Selected.Parent)
and Assigned(tvXML.Selected.Parent.Data) and
(TElXMLDOMNode(tvXML.Selected.Parent.Data) is TElXMLDOMElement) then
TElXMLDOMElement(tvXML.Selected.Parent.Data).RemoveAttributeNode(TElXMLDOMAttr(N));
end;
UpdateXML;
end;
procedure TfrmMain.btnEncryptClick(Sender: TObject);
var
Encryptor: TElXMLEncryptor;
SymKeyData, SymKEKData: TElXMLKeyInfoSymmetricData;
RSAKeyData: TElXMLKeyInfoRSAData;
X509KeyData: TElXMLKeyInfoX509Data;
{$ifndef SBB_EXCL_XML_PGP}
PGPKeyData: TElXMLKeyInfoPGPData;
{$endif}
F: {$ifndef DELPHI_NET}TFileStream{$else}FileStream{$endif};
Node, EncNode: TElXMLDOMNode;
Buf: ByteArray;
begin
SymKeyData := nil;
SymKEKData := nil;
RSAKeyData := nil;
X509KeyData := nil;
{$ifndef SBB_EXCL_XML_PGP}
PGPKeyData := nil;
{$endif}
frmEnc.LockOpt := False;
if frmEnc.ShowModal = mrOK then
begin
Encryptor := TElXMLEncryptor.Create(Self);
try
Encryptor.EncryptKey := frmEnc.EncryptKey;
Encryptor.EncryptionMethod := frmEnc.EncryptionMethod;
Encryptor.KeyName := frmEnc.KeyName;
Encryptor.EncryptedDataType := frmEnc.EncryptedDataType;
if Encryptor.EncryptKey then
begin
Encryptor.KeyEncryptionType := frmEnc.KeyEncryptionType;
Encryptor.KeyTransportMethod := frmEnc.KeyTransportMethod;
Encryptor.KeyWrapMethod := frmEnc.KeyWrapMethod;
SymKeyData := TElXMLKeyInfoSymmetricData.Create(True);
// generate random Key & IV
case Encryptor.EncryptionMethod of
xem3DES:
begin
SymKeyData.Key.Generate(T3DESKeySize * 8);
SymKeyData.Key.GenerateIV(8 * 8);
end;
xemAES:
begin
SymKeyData.Key.Generate(SizeOf(TAESKey256) * 8);
SymKeyData.Key.GenerateIV(16 * 8);
end;
xemCamellia:
begin
SymKeyData.Key.Generate(32 * 8); // 16, 24, 32
SymKeyData.Key.GenerateIV(16 * 8);
end;
xemDES:
begin
SymKeyData.Key.Generate(TDESKeySize * 8);
SymKeyData.Key.GenerateIV(8 * 8);
end;
xemRC4:
begin
SymKeyData.Key.Generate(16 * 8); // 1..32
end;
end;
Encryptor.KeyData := SymKeyData;
if Encryptor.KeyEncryptionType = xetKeyWrap then
begin
SymKEKData := TElXMLKeyInfoSymmetricData.Create(True);
{$ifndef DELPHI_NET}
F := TFileStream.Create(frmEnc.KeyFile, fmOpenRead or fmShareDenyWrite);
{$else}
F := FileStream.Create(frmEnc.KeyFile, FileMode.Open, FileAccess.Read);
{$endif}
try
SymKEKData.Key.Load(F);
finally
FreeAndNil(F);
end;
Encryptor.KeyEncryptionKeyData := SymKEKData;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?