想象以下情况:
您需要从访问您的网站的用户那里获取一个密钥(在非对称情况下为用户的公共密钥 ),并希望浏览器记住私有部分,而不会因冗长的导入过程而困扰用户。 老实说,实际上,您甚至不希望用户处理加密详细信息,这些详细信息是许多用户无法知道或不正确知道的。 它应该简单地工作,并且在最佳情况下,用户甚至都不应该注意到加密正在发挥作用! 想象一下,例如,一个企业范围的证书颁发机构 ,员工可以在其中申请证书或续订登录到公司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 HTTPGET
andPOST
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*/@Overrideprotected 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*/@Overrideprotected void doPost(final HttpServletRequest request,final HttpServletResponse response)throws ServletException, IOException {processRequest(request, response);} }
在这种情况下,用于响应的ContentType是application / x-x509-user-cert。
就这样。 用户输入详细信息并单击按钮后,他应该在浏览器的证书存储中找到新证书:
关于SPKAC 轻巧拆卸的最后一句话: BouncyCastle可以帮助您与ASN.1和DER野兽战斗!
翻译自: https://www.javacodegeeks.com/2013/06/browser-based-key-generation-and-interaction-with-the-browsers-keycertificate-store.html