本文记叙的是一次基于SSL的socket通讯程序开发中,有关证书,签名,身份验证相关的步骤。我们的场景下,socket服务端是java语言编写的,客户端是c语言。使用了一个叫做matrixssl的c语言库。自己做CA签名,不等同于“自签名”。自签名的情况,RSA的公钥私钥只有一对,用私钥对公钥证书做签名。而我们的场景是,自己做CA,有一个CA的公钥私钥对。而socket的服务端也有一个公钥私钥对。用CA的私钥对socket服务端的公钥证书做签名。opensslgenrsa-outca.key1024(这里我们没有用des3加密。可以增加一个-des3参数加密,详情可以mangenrsa)opensslreq-new-x509-days36500-keyca.key-outca.crt(这一步的时候需要在提示之下输入许多信息,包括国家代码,省份,城市,公司机构名等)生成server端的私钥key:opensslgenrsa-outserver.key1024生成server端的req文件(这一步生成的req文件,包含公钥证书,外加身份信息,例如国家,省份,公司等。用它提交给ca,让ca来对它做签名):opensslreq-new-keyserver.key-outserver.csr用CA的私钥对server的req文件做签名,得到server的证书:opensslx509-req-days3650-inserver.csr-CAca.crt-CAkeyca.key-CAcreateserial-outserver.crt(注:如果第一次使用openssl,报告一些相关的文件找不到之类的错误,可能需要先执行2个命令:touch/etc/pki/CA/index.txt和echo'01'>/etc/pki/CA/serial)以上得到的server.crt就是服务端的证书文件。(有很多软件中需要各种不同证书存储格式,可能需要各种转换。如PEM,P12等,我们的场景下也需要一点转换,下文会描述。刚开始做这些的同学可能会觉得证书,以及格式等非常的混乱。这个时候能做的就是冷静下来,耐心的理清楚TLS,RSA等原理,多看看openssl的man文档)不知道把ca.crt叫做CA的证书文件是否妥当,但是可以确定的是,客户端使用ca.crt可以校验server的身份。server在SSL/TLS握手的过程中会下发自己的证书,而这个证书是经过CA签名的。CA签名的时候使用的是CA自己的私钥,而ca.crt则包含了CA的公钥,可以用于检验这一签名,以确认是否是自己签的名。服务端需要使用的文件是:server私钥(key),server证书。客户端需要使用的文件是:CAfile(ca的证书,用以验证server下发的证书)我们的server端使用java,使用p12(PKCS12)格式的证书。使用openssl可以进行格式转换:opensslpkcs12-export-clcerts-inserver.crt-inkeyserver.key-outserver.p12可以看到输出的server.p12中应该包含了server.key和server.crt的内容。我们的c语言客户端直接使用CA文件:ca.crt.我们也用java写过客户端,java使用CA文件格式为jks。那么可能需要一个转换,这里使用的是java的bin目录下的keytool:keytool-importcert-aliasCA-fileca.crt-keystoreca.jks转换的时候要求输入一个密码。这样就把ca.crt转换为了ca.jks格式。下面附上部分socket服务端和java版的客户端的代码。c的就不贴了,用的matrixssl。java服务端(mina)代码片段:Stringfile="/file/path/server.p12";StringkeyType="PKCS12";char[]password="passwd".toCharArray();KeyStoreks=KeyStore.getInstance(keyType);ks.load(newFileInputStream(file),password);KeyManagerFactorykmf=KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());kmf.init(ks,password);SSLContextctx=SSLContext.getInstance("TLS");ctx.init(kmf.getKeyManagers(),null,null);SslFiltersslFilter=newSslFilter(ctx);//在mina的acceptor中增加这个filter就可以了。acceptor.getFilterChain().addLast("ssl",newSslFilter(createSslContext()));java版客户端(mina)代码片段://trustStringfile="/data/tmp/ca.jks";StringkeyType="jks";char[]password="123456".toCharArray();KeyStoreks=KeyStore.getInstance(keyType);ks.load(newFileInputStream(file),password);TrustManagerFactorytmf=TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());tmf.init(ks);SSLContextsslContext=SSLContext.getInstance("TLS");sslContext.init(null,tmf.getTrustManagers(),null);SslFiltersslFilter=newSslFilter(sslContext);sslFilter.setUseClientMode(true);//server端是addLast,这个却是addFirst.这个顺序不能搞错了。connector.getFilterChain().addFirst("sslFilter",sslFilter);
数字证书CA,也就是您的个人数字证书,通俗地说就是您在网络上的个人身份证。CA数字证书就向您房屋防盗系统的最后一道屏障,就如同房屋的门禁系统,对每个进入者进行有效的身份识别,防止未授权人员的进入。不知道这样说够不够简单。希望您能用得上。祝您一切顺利。