1,需要訪問的東西是USBKey宴杀,里面有2張證書癣朗,分別是簽名和加密證書。
2旺罢,通過https方式上傳xml旷余,上傳之前必須先給xml簽名,xml的簽名必須通過數(shù)字證書的私鑰簽名扁达。
3正卧,私鑰的訪問通過capicom.dll。這是微軟提供的一個(gè)com組件跪解。
4炉旷,js、delph叉讥、c#都可以訪問私鑰窘行。
1,因?yàn)槭莄om組件节吮,需要先在本機(jī)注冊(cè)抽高,有32和64區(qū)別,32和64必須放在各自系統(tǒng)目錄對(duì)應(yīng)的地方透绩。
2翘骂,注冊(cè)Regsvr32 capicom.dll
3壁熄,學(xué)習(xí)的重點(diǎn),搞懂com提供的對(duì)象碳竟,并搞懂有哪些方法草丧。
JavaScript方式
1,創(chuàng)建對(duì)象。
var MyStore = new ActiveXObject("CAPICOM.Store");
2莹桅,調(diào)用Open方法
參數(shù)1
參數(shù)2 storeName = "My"
參數(shù)3
MyStore.Open(CAPICOM_CURRENT_USER_STORE, storeName, CAPICOM_STORE_OPEN_READ_WRITE);
3,遍歷MyStore.Certificates
for ( i = 1; i <= MyStore.Certificates.count; i++) {
var str = "cert: " + MyStore.Certificates(i).subjectName + " SHA: " + MyStore.Certificates(i).thumbprint;
昌执。。诈泼。懂拾。。
}
4,open完畢铐达,如果有多個(gè)證書岖赋,可以下面調(diào)用,select會(huì)返回選中的證書,想拿到證書,必須下面2行代碼一起寫瓮孙。
var xx = MyStore.Certificates.select();
Certificate = xx(1);
加密
1唐断,創(chuàng)建CAPICOM.EnvelopedData對(duì)象
var EnvelopedData = new ActiveXObject("CAPICOM.EnvelopedData");
2,指定算法杭抠,CALG_3DES脸甘,CALG_DES,CALG_RC4
EnvelopedData.Algorithm.Name = xx;
3偏灿,指定加密內(nèi)容
EnvelopedData.Content = frm.srcText.value;
4丹诀,指定加密證書
EnvelopedData.Recipients.Add(Certificate);
5,調(diào)用方法加密
frm.desEnvText.value = EnvelopedData.Encrypt(CAPICOM_ENCODE_BASE64);
解密
1,解密和加密一致,采用統(tǒng)一對(duì)象
var DevelopedData = new ActiveXObject("CAPICOM.EnvelopedData");
2,添加解密證書菩混,加密和解密證書必須是同一個(gè)
DevelopedData.Recipients.Add(Certificate);
3忿墅,調(diào)用解密方法,參數(shù)是需要解密的文本沮峡。
DevelopedData.Decrypt(frm.desEnvText.value);
4,解密成功之后的內(nèi)容疚脐,在Content返回
frm.unEnvText.value = DevelopedData.Content;
Delphi方式獲取證書
1,先了解delphi是如何調(diào)用Com組件。然后手工生成CAPICOM_TLB單元邢疙,操作USBKey就是調(diào)用單元提供的類和接口棍弄。
2,delphi提供的類和js提供的類一致疟游,方法名也一致呼畸, 參數(shù)也一致。也就是JS能訪問的方法delphi都能訪問颁虐。
證書遍歷
var
dllHandle: THandle;
EnData: TStore;
i: integer;
KeyUsage: IKeyUsage;
cert: ICertificate;
cert2: ICertificate2;
begin
dllHandle:= LoadLibrary(LPCTSTR('capicom.dll'));
try
EnData := TStore.Create(nil);
EnData.Open(CAPICOM_CURRENT_USER_STORE,'My',CAPICOM_STORE_OPEN_READ_ONLY);
for i:=1 to EnData.Certificates.Count-1 do
begin
cert := IInterface(EnData.Certificates.item[i]) as ICertificate;
ShowMessage(cert.SubjectName );
cert2 := IInterface(EnData.Certificates.item[i]) as ICertificate2;
ShowMessage(cert2.PrivateKey.ContainerName);
// ShowMessage(EnData.Certificates.Item[i].subjectname+#13
// + EnData.Certificates.Item[i].SerialNumber + #13
// +VarToStr(EnData.Certificates.Item[i].Version)+#13
// +EnData.Certificates.Item[i].IssuerName+#13
// + DateTimeToStr(EnData.Certificates.Item[i].ValidFromDate) + #13
// + DateTimeToStr(EnData.Certificates.Item[i].ValidToDate) + #13
// );
// EnData.Certificates.Item[i].display;
// EnData.Certificates.Item[i].KeyUsage.IsCritical;
if EnData.Certificates.Item[i].HasPrivateKey then
begin
// ShowMessage('有私鑰');
end;
end;
finally
EnData.Free;
FreeLibrary(dllHandle);
end;
if CoInitialize(nil)=S_FALSE then
CoUnInitialize;
end;
加密
var
dllHandle: THandle;
EnData: TEncryptedData;
i: integer;
KeyUsage: IKeyUsage;
begin
dllHandle:= LoadLibrary(LPCTSTR('capicom.dll'));
try
Memo1.Lines.Clear;
EnData := TEncryptedData.Create(nil);
EnData.Algorithm.Name:= CAPICOM_ENCRYPTION_ALGORITHM_3DES;
EnData.Algorithm.KeyLength:= CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM;
EnData.SetSecret('Something Secret',CAPICOM_SECRET_PASSWORD);
EnData.Content:= Edit1.Text;
Memo1.Lines.Add(EnData.Encrypt(CAPICOM_ENCODE_BASE64));
finally
EnData.Free;
FreeLibrary(dllHandle);
end;
if CoInitialize(nil)=S_FALSE then
CoUnInitialize;
end;
判斷簽名證書蛮原、加密證書
var
vStore: TStore;
iCnt: Integer;
IBaseIntf: IInterface;
ICert2Dsp: ICertificate2Disp;
begin
if ICert2 = nil then
begin
vStore := TStore.Create(nil);
vStore.Open(CAPICOM_CURRENT_USER_STORE, 'My', CAPICOM_STORE_OPEN_READ_ONLY);
for iCnt := 1 to vStore.Certificates.Count do
begin
IBaseIntf := vStore.Certificates.Item[iCnt];
try
if IBaseIntf.QueryInterface(ICertificate2Disp, ICert2Dsp) = 0 then
begin
//確認(rèn)硬件是否連接
if ICert2Dsp.HasPrivateKey then
begin
//確認(rèn)是否為指定CSP提供商
if (ICert2Dsp.PrivateKey.KeySpec = CAPICOM_KEY_SPEC_SIGNATURE ) then
begin
ShowMessage('one');
IBaseIntf.QueryInterface(IID_ICertificate2, ICert2);
// IBaseIntf.QueryInterface(IID_ICertificate, ICert);
FPublicKey := ICert2Dsp.publickey.EncodedKey.Format(True);
FPKLength := ICert2Dsp.publickey.Length;
FAlgType := ICert2Dsp.publickey.Algorithm.FriendlyName;
end;
end;
end;
except
//某些不支持CAPICOM的,會(huì)出現(xiàn)異常
ICert2 := nil;
end;
end;
end;
end;
因?yàn)閐elphi7沒提供直接簽名xml的工具類另绩,需要手工拼接xml儒陨,xml的簽名可以選擇c#花嘶,c#訪問USBKey的方式和delphi一樣。