基于浏览器的密钥生成以及与浏览器的密钥/证书存储的交互

本文介绍了如何利用HTML5的KeyGen标签在浏览器中生成密钥对,使得用户无需手动处理加密细节。通过KeyGen,用户的公共密钥和服务器质询签名会被发送到服务器,服务器则回应X.509证书,该证书与私钥关联并存储在浏览器的证书存储区。在Java中,创建证书的过程涉及服务器端的Servlet处理表单提交,以确保通信安全。BouncyCastle库可用于处理ASN.1和DER编码。
摘要由CSDN通过智能技术生成

想象以下情况:
您需要从访问您的网站的用户那里获取一个密钥(在非对称情况下为用户的公共密钥 ),并希望浏览器记住私有部分,而不会因冗长的导入过程而困扰用户。 老实说,实际上,您甚至不希望用户处理加密详细信息,这些详细信息是许多用户无法知道或不正确知道的。 它应该简单地工作,并且在最佳情况下,用户甚至都不应该注意到加密正在发挥作用! 想象一下,例如,一个企业范围的证书颁发机构 ,员工可以在其中申请证书或续订登录到公司Webmail系统所需的证书。 这不是员工主要任务的一部分,因此该过程必须简单,快速并且无需阅读任何内容。 非常感谢(或本例中为Netscape )HTML,因为HTML 5甚至是独立于浏览器的,也是官方标准的一部分,带有专用于密钥生成的标签: <KeyGen />。 简而言之,标记可以强制用户的浏览器创建非对称密钥对,对相应的公共密钥和服务器提供的质询进行签名,最后将其发送回服务器(更确切地说,发送至表单操作中定义的位置)属性)。 私钥会自动加密并存储在浏览器的密钥存储区中。 用于公共密钥,质询和签名封装的格式称为SPKAC 。 如果服务器以X.509证书作为响应,则证书直接链接到私钥并存储在浏览器的证书存储区中。 结果,浏览器现在拥有服务器提供的(可能是新创建的)证书和相应的私钥。 所有这些只需单击一次提交按钮即可。 (是的,也许用户还应该在表单字段中添加一些详细信息……)这是在Java中的操作方法。 为了简单起见,我们将通过直接注册为Servlet在服务器端使用快速且肮脏的解决方案。

首先,我们将从初始网站开始,该网站提供一个表格,其中必须输入证书申请者的一些详细信息。 请注意,这些表单域不是由签名与新生成私钥保护! 此签名仅保护公共密钥,而在这种情况下(为简单起见)它是硬编码的,但是必须是服务器在现实世界中选择的新值,才能保护挑战。 因此,必须保护两者:网站的交付(包括表单)(它包含安全性关键值,挑战,表单操作……必须受到完整性保护)以及将数据传输回服务器。 再一次, 如果您无法保护通信并至少确保安全目标的完整性,那么攻击者可能会破坏您的整个安全概念!

<form action="CreateCertificate" method="POST">
<table>
       <tbody>
                <tr>
                    <td>Country name</td>
                    <td>C</td>
                    <td><input name="c" type="text" value="" /></td>
                </tr>
                <tr>
                    <td>Common name</td>
                    <td>CN</td>
                    <td><input name="cn" type="text" value="" /></td>
                </tr>
                <tr>
                    <td>Organizational unit</td>
                    <td>OU</td> 
                    <td><input name="ou" type="text" value="" /></td>
                </tr>
                <tr>
                    <td>Organization</td>
                    <td>O</td>
                    <td><input name="o" type="text" value="" /></td>
                </tr>
                <tr>
                    <td></td>
                    <td><keygen challenge="replaceMe" keyparams="2048" keytype="rsa" 
                      name="newSPKAC"></keygen></td>
                    <td><input type="submit" value="Generate!" /></td>
                </tr>
       </tbody>
</table>
</form>

在服务器端,必须为表单操作目标注册一个处理类。 这是在您的web.xml配置文件中完成的。

<web-app version="3.0" xmlns:xsi="..." xmlns="..." xsi:schemalocation="...">
    <servlet>
        <servlet-name>CreateCertificate</servlet-name>
        <servlet-class>
            com.blogspot.armoredbarista.examples.certificates.CreateCertificate
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CreateCertificate</servlet-name>
        <url-pattern>/CreateCertificate</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

这将导致对路径/ CreateCertificate的任何调用均由CreateCertificate类处理。 反过来,CreateCertificate类执行名称中所期望的操作:它创建一个证书,其中包括收到的公共密钥和请求者的详细信息。 公钥和质询包含在SPKAC结构中,该结构由KeyGen标签创建(在这种情况下,此名称由名称newSPKAC标识)。

public class CreateCertificate extends HttpServlet {
    /**
     * Processes requests for both HTTP GET and POST methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(final HttpServletRequest request,
            final HttpServletResponse response)
            throws ServletException, IOException {

        OutputStream out = response.getOutputStream();
        byte[] content = "An error occured".getBytes("UTF-8");
        try {
            String c = request.getParameter("c");
            String cn = request.getParameter("cn");
            String o = request.getParameter("o");
            String ou = request.getParameter("ou");
            String newSPKAC = request.getParameter("newSPKAC");

            X509Certificate cert = createCertificate(c, cn, ou, o, newSPKAC);
            content = cert.getEncoded();

            response.setContentType("application/x-x509-user-cert");
            response.setHeader("Pragma", "No-Cache");
            response.setDateHeader("EXPIRES", -1);
        } catch (...) {
          // error processing
        } finally {
            out.write(content);
            out.flush();
            out.close();
        }
    }

    /**
     * Handles the HTTP
     * GET method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(final HttpServletRequest request,
            final HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * POST method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(final HttpServletRequest request,
            final HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

在这种情况下,用于响应的ContentType是application / x-x509-user-cert。

就这样。 用户输入详细信息并单击按钮后,他应该在浏览器的证书存储中找到新证书:

关于SPKAC 轻巧拆卸的最后一句话: BouncyCastle可以帮助您与ASN.1DER野兽战斗!


翻译自: https://www.javacodegeeks.com/2013/06/browser-based-key-generation-and-interaction-with-the-browsers-keycertificate-store.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值