最新消息:

IE中自动安装根数字证书

技术 admin 4143浏览 7评论

基本思路:

1、在XP、Windows 2003的IE上,通过XEnroll.dll控件来完成根数字证书的自动安装。

2、在Vista,Windows 2008,Windows 7 的IE上,需要使用CertEnroll.dll来自动完成根数字证书的自动安装。

3、XEnroll.InstallPKCS7只适用于自动安装根证书。XEnroll.acceptPKCS7 用于安装用户数字证书,但需要配合CSR(Certificate signing request)才能够使用。要实现自动安装用户证书:

在IE中:需要配合Enroll.createPKCS10CSR来生成CSR(Certificate signing request)

在Firefox中:需要配合使用html的keygen标签来生成CSR

4、如果只需要能够下载证书并安装,而不要在IE浏览器中完成证书注销、证书申请等功能,可以采用下载证书文件的方式,MIME Type可以采用

application/x-pkcs12、application/pkcs-12

几个与PKI证书相关的MIME Type:

application/x-x509-ca-cert、application/x-x509-user-cert、application/pkcs10、application/x-pkcs10、application/pkcs-12、

application/x-pkcs12、application/x-pkcs7-signature、application/pkcs7-mime、application/x-pkcs7-mime、

application/pkcs7-mime、application/x-pkcs7-mime、application/x-pkcs7-certreqresp、application/pkcs7-signature

  测试代码:

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="java.lang.*,java.io.*" %>
<html>
<head>
<title>IE中自动安装数字证书测试</title>
</head>

<body>
IE中使用XEnroll.InstallPKCS7自动安装根数字证书<br/>
 备注:这里测试的根证书采用Base64编码 X.509格式(CER)<br/>
<%

StringBuffer server_cert =new StringBuffer();
try {
    String realPath = this.getClass().getClassLoader().getResource("liangchuan.cer").getPath();
    File file = new File(realPath);
    if (!file.exists()) {
        out.println("<HTML><BODY><P>");
        out.println("<h2>根证书文件不存在</h2> <br/>");
        out.println("</P></BODY></HTML>");
        out.flush();
        out.close();
    }else{
        BufferedReader bf=new BufferedReader(new FileReader(file));
        String line=null;
        while((line=bf.readLine())!=null)
            server_cert.append(line);

        bf.close();

    }
}catch(Exception e){
    out.println("<HTML><BODY><P>");
    out.println("<h2>读取证书文件出错</h2> <br/>");
    out.println(e.toString());
    out.println("</P></BODY></HTML>");
    out.flush();
    out.close();
}

String Agent = request.getHeader("User-Agent");
StringTokenizer st = new StringTokenizer(Agent,";");
st.nextToken();
String userBrowser = st.nextToken();
String userOS = st.nextToken();
out.println("你的操作系统为:");
out.println(userOS);
String activexLib="XEnroll";

//检查是否是Windows Vista,Windows 2008,Windows 7,在Vista,Windows 2008,Windows 7上,需要使用 CertEnroll.dll
//Windows 2008 Server, IE7 User-Agent header: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2;...
//Windows Vista, IE7 User-Agent header: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0;...
//Windows 7,IE8 User-Agent header: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1;...

if(userOS.equals("Windows NT 6.0") || userOS.equals("Windows NT 6.1")|| userOS.equals("Windows NT 5.2"))
    activexLib="CertEnroll";

String sPKCS7=server_cert.toString();
%>

<% if(activexLib.equals("XEnroll"))
{ %>
    <object id="XEnroll" classid="clsid:127698e4-e730-4e5c-a2b1-21490a70c8a1" codebase="xenroll.dll"></object>
    <SCRIPT language="VBSCRIPT">
        ON ERROR resume next
        sPKCS7 = "<%= sPKCS7 %>"
        //XEnroll.InstallPKCS7用于安装根证书。
        XEnroll.InstallPKCS7(sPKCS7)

        if err.Number <> 0 then
            if err.number = -2146885628 then
                MsgBox "Keyset does not exist"
            else
                MsgBox "证书下载时出错,错误号="&err.description
            end if
        else
            MsgBox "证书已成功装入"
        end if
</script>
<% } else {%>

//方法来源:
//http://blogs.msdn.com/alejacma/archive/2009/01/28/how-to-create-a-certificate-request-with-certenroll-javascript.aspx
//Vista下由于暂时没有测试环境,方法尚待验证

    <object id="objCertEnrollClassFactory" classid="clsid:884e2049-217d-11da-b2a4-000e7bbb2b09"></object>
    <script language="javascript">
    function InstallCert()
    {
        document.write("<br>Installing certificate...");
        try {
            // Variables
            var objEnroll = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509Enrollment")
            var sPKCS7 = "<%= sPKCS7 %>"
            objEnroll.Initialize(1); // ContextUser
            objEnroll.InstallResponse(0, sPKCS7, 6, ""); // AllowNone = 0, XCN_CRYPT_STRING_BASE64_ANY = 6
        }
        catch (ex) {
            document.write("<br>" + ex.description);
            return false;
        }

    return true;
    }

    InstallCert();

    </script>

<% } %>
<%
/*
out.println("用下载方式下载p12格式的文件下载后安装"); 
ClassLoader cl = this.getClass().getClassLoader();
try {
    InputStream is = cl.getResourceAsStream("liangchuan.p12");
    //response.setContentType("application/x-x509-ca-cert");
    response.setContentType("application/x-pkcs12");
    response.addHeader("Content-Disposition", "attachment; filename=liangchuan.p12");
    OutputStream os = response.getOutputStream();
    //InputStream is = new FileInputStream(fileName);
    while (is.available() > 0) {
        char c = (char) is.read();
        os.write(c);
    }
    os.flush();
    is.close(); 
} catch (Exception e) { 

    out.println("<HTML><BODY><P>");
    out.println("<h2>下载证书文件出错</h2> <br/>");
    out.println(e.toString());
    out.println("</P></BODY></HTML>");
    out.flush();
    out.close(); 

}
*/
%>
</body>
</html>

参考资料:

How to create a certificate request with CertEnroll (JavaScript)

Certificate-Related Changes for Windows Vista

How to use Certificate Services Web enrollment pages together with Windows Vista or Windows Server 2008

转载请注明:出家如初,成佛有余 » IE中自动安装根数字证书

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (7)

  1. 怎么样自动删除根证书呢 我用store.remove(Certificate)删除 就报异常了 帮我解决下好吗
    adad14年前 (2010-04-14)回复
  2. 我想用http方式给客户提供下载加密pdf的同时安装pfx证书 在XP,win2003的用户用XEnroll安装成功了,win2008 win7的用CertEnroll弹出了证书安装验证后报“CertEnroll::CX509Enrollment::InstallResponse: 已处理证书链,但是在不受信任提供程序信任的根证书中终止。 0x800b0109 (-2146762487)错误” 是否一定需要CA和SSL?
    bestlife14年前 (2010-10-29)回复
  3. 与bestlife 同样的问题 关注
    joshua14年前 (2010-11-18)回复
  4. bestlife,将InstallResponse方法第一个参数设为4可以消除此错误。见:http://msdn.microsoft.com/en-us/library/aa378051(v=vs.85).aspx 但问题是,CA证书被安装在了“中级证书颁发机构”里面,而不是“受信任的根证书颁发机构”! objEnroll.InstallResponse(4, sPKCS7, 6, "");
    邪恶明13年前 (2011-02-21)回复
  5. CA证书被安装在了“中级证书颁发机构”里面,而不是“受信任的根证书颁发机构”! 这个问题如何解决?
    hi13年前 (2011-04-06)回复