• 用openssl生成SSL使用的私钥和证书,并自己做CA签名(转)


     本 文记叙的是一次基于SSL的socket通讯程序开发中,有关证书,签名,身份验证相关的步骤。 我们的场景下,socket服务端是java语言编写的,客户端是c语言。使用了一个叫做matrixssl的c语言库。自己做CA签名,不等同于“自签 名”。 自签名的情况,RSA的公钥私钥只有一对,用私钥对公钥证书做签名。而我们的场景是,自己做CA,有一个CA的公钥私钥对。 而socket的服务端也有一个公钥私钥对。 用CA的私钥对socket服务端的公钥证书做签名。

    openssl genrsa -out ca.key 1024

     (这里我们没有用des3加密。 可以增加一个-des3参数加密,详情可以man genrsa) 

     

    openssl req -new -x509 -days 36500 -key ca.key -out ca.crt

     (这一步的时候需要在提示之下输入许多信息,包括国家代码,省份,城市,公司机构名等) 

     

    生成server端的私钥key:

    openssl genrsa -out server.key 1024

     

     生成server端的req文件(这一步生成的req文件,包含公钥证书,外加身份信息,例如国家,省份,公司等。用它提交给ca,让ca来对它做签名 ):

    openssl req -new -key server.key -out server.csr

     

    用CA的私钥对server的req文件做签名,得到server的证书: 

    openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.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证书。 
    客户端需要使用的文件是:CA file(ca的证书,用以验证server下发的证书)

    我们的server端使用java, 使用p12(PKCS12)格式的证书。使用openssl可以进行格式转换: 

    openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12

    可以看到输出的server.p12中应该包含了server.key和server.crt的内容。

    我们的c语言客户端直接使用CA文件: ca.crt.

    我们也用java写过客户端, java使用CA文件格式为 jks。那么可能需要一个转换,这里使用的是java的bin目录下的keytool: 

    keytool -importcert -alias CA -file ca.crt -keystore ca.jks

    转换的时候要求输入一个密码。这样就把ca.crt转换为了 ca.jks格式。

    下面附上部分socket服务端和java版的客户端的代码。c的就不贴了,用的matrixssl。

    java服务端(mina)代码片段:

    String file = "/file/path/server.p12";
            String keyType = "PKCS12"; char[] password = "passwd".toCharArray();
            KeyStore ks = KeyStore.getInstance(keyType);
            ks.load(new FileInputStream(file), password);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(ks, password);
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(kmf.getKeyManagers(), null, null);
    
            SslFilter sslFilter = new SslFilter(ctx); // 在mina的acceptor中增加这个filter就可以了。 
    acceptor.getFilterChain().addLast("ssl", new SslFilter(createSslContext()));

     java版客户端(mina)代码片段:

    // trust String file = "/data/tmp/ca.jks";
            String keyType = "jks"; char[] password = "123456".toCharArray();
            KeyStore ks = KeyStore.getInstance(keyType);
            ks.load(new FileInputStream(file), password);
            TrustManagerFactory tmf = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(ks);
    
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            SslFilter sslFilter = new SslFilter(sslContext);
            sslFilter.setUseClientMode(true); // server端是addLast ,  这个却是 addFirst. 这个顺序不能搞错了。
     connector.getFilterChain().addFirst("sslFilter", sslFilter);
  • 相关阅读:
    IOS开发关于测试的好的网址资源
    创建型模式--工厂模式
    在XcodeGhost事件之后,获取更纯净的Xcode的方法。
    算法积累:解决如何获取指定文件夹路径或者文件路径下所有子文件后缀为.h .m .c的文本的行数
    结构型模式--装饰模式
    设计模式 总揽 通过这篇随笔可以访问所需要了解的设计模式
    IOS之未解问题--关于IOS图像渲染CPU和GPU
    链接
    Matlab2014下载和破解方法,以及Matlab很好的学习网站
    苹果Mac隐藏壁纸在哪里?Mac隐藏壁纸查找教程
  • 原文地址:https://www.cnblogs.com/zhengah/p/5007938.html
Copyright © 2020-2023  润新知