将Capicom调用代码封装到ActiveX——解决javascript调Capicom读取数字证书信息时,IE弹出安全提示的问题
1.使用Capicom读取数字证书的方法
一、使用javascript方法:
<object id="oCAPICOM" codebase="http://download.microsoft.com/download/E/1/8/E18ED994-8005-4377-A7D7-0A8E13025B94/capicom.cab#version=2,0,0,3" classid="clsid:A996E48C-D3DC-4244-89F7-AFA33EC60679"> </object><script language="javascript">
var CAPICOM_CURRENT_USER_STORE = 2
var CAPICOM_STORE_OPEN_READ_WRITE = 1function auto_run() {
var CertSubject;
var CertSerial;
var oSignerCert;
var oSelects;
var oSignerCert;var st = new ActiveXObject("CAPICOM.Store");
var Certificate = new ActiveXObject("CAPICOM.Certificate");st.open(CAPICOM_CURRENT_USER_STORE, "my", CAPICOM_STORE_OPEN_READ_WRITE);
if (st.Certificates.Count == 1) {
oSignerCert = st.Certificates(1);
}
else {
oSelects = new ActiveXObject("CAPICOM.Certificates");
oSelects = st.Certificates.Select();
oSignerCert = oSelects(1);
}document.all.text1.value = oSignerCert.Getinfo(6);
document.all.text2.value = oSignerCert.SerialNumber;}
</script>
二、使用Cryptography Objects:
详见: http://msdn.microsoft.com/en-us/library/aa380254(v=VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms867087
SDK下载:http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=25281
注意MSDN的提示,原文如下:
Requirements
Redistributable
CAPICOM 2.0 or later on Windows Server 2003, Windows XP, Windows 2000 Server with SP3 and later, and Windows 2000 Professional with SP3 and later
DLL
- Capicom.dll
2.实现读取数字证书序列号功能时遇到的问题
一、解决浏览器弹出安全提示的问题:
如标题中所说,当使用JS调用Capicom时,IE会弹出安全提示。MSDN原文解释如下:
Important When this method is called from a web script, the script needs to access digital certificates on the local computer. If you allow the script to access your digital certificates, the website from which the script is run will also gain access to any personal information stored in the certificates. The first time this method is called from a particular domain, a dialog box is generated in which the user must indicate whether access to the certificates should be allowed. Stores opened from a web script automatically force the CAPICOM_STORE_OPEN_EXISTING_ONLY flag.
我想到的一种解决办法就是自己用C#写一个ActiveX,然后再用脚本调用这个ActiveX开放的方法来读取数字证书的信息,这样就跳过了浏览器的安全检查。实际验证,成功解决了IE弹出安全提示的问题。
我的这个ActiveX实现的功能是读取USBKEY数字证书序列号及过期时间(使用SDK中的getChainFromStore方法获得证书路劲找到指定的证书,然后读取需要的信息),代码就不贴出来了。(项目需要引用Capicom这个COM组件,没找到就用Regsvr32.exe Capicom.dll命令注册)
关于怎么用.NET开发Activex控件可以看我的另一篇文章(含源码下载):C#实现的ActiveX截图打印控件
强调两点:1.ActiveX项目属性的“生成”项中“为COM Inerop 注册”勾选之后本地调试会自动注册该控件(Windows7需要以管理员运行该项目才行)。可以使用“Microsoft Visual Studio 8\Common7\Tools\Bin”下的OleView.Exe查看是否注册成功(以2005为例)。
2.安装文件项目中引用的ActiveX控件项目或者其DLL文件的属性中,Register必须设置成“vsdrpCOM”。
二、解决C#开发的ActiveX控件或者C++开发的.ocx扩展名的ActiveX在IE下不能成功安装,需要降低浏览器权限,或者根本装不成功的问题
这个还是与IE的证书检查有关,一种解决办法就是制作ActiveX安装文件,而不是制作.dat包之类的。
C#开发ActiveX只要注意了我上面提到的属性设置应该就不会有问题了。这里用到了Capicom,还不得不写成安装文件以注册Capicom。
至于.ocx扩展名的ActiveX控件,需要写程序自动注册,用到的命令是:Regsvr32.exe /s youfilename.ocx
这里的/s达到的效果就是不弹出注册成功与否的提示。
使用程序注册.ocx扩展名的ActiveX控件:
/// <summary>
/// 复制文件到系统安装路劲
/// </summary>
/// <param name="fileName">文件名</param>
private void AddResourceFile(string fileName)
{
try
{
if (!File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\" + fileName))//不存在文件则创建
{
Assembly asm = Assembly.GetExecutingAssembly();using (Stream stream = asm.GetManifestResourceStream("InstallActiveX." + fileName))//文件已经以“嵌入资源文件”的形式添加到项目中
{
int len = (int)stream.Length;
byte[] byts = new byte[len];stream.Read(byts, 0, len);
stream.Close();using (FileStream fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\" + fileName, FileMode.Create))
{
fs.Write(byts, 0, len);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "在" + ex.StackTrace);
}
}class Register
{
/// <summary>
/// 使用regsvr注册控件
/// </summary>
/// <param name="strDll">文件名</param>
public void RegisterDll(string strDll)
{
try
{
Process p = new Process();
p.StartInfo.FileName = "Regsvr32.exe";
p.StartInfo.Arguments = " " + strDll;
p.Start();
p.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "在" + ex.StackTrace);
}
}
}使用:
AddResourceFile("youfilename.ocx");//先复制文件
Register r = new Register();
r.RegisterDll("/s youfilename.ocx");//注册ocx关于怎么让这段程序在安装时运行,方法是:新建一个安装程序类,然后把该类所在的类库添加到“自定义操作”的“安装”文件夹。
添加过程是,选择安装文件项目,右键选择“视图”->“自定义操作”。
三、解决.Net Framework如何打包到安装文件的问题
设置如图中所示:
在安装文件项目的属性中点击“系统必备”设置。