资讯详情

Linux openssl 生成证书的详解

前言

1 概念

2 环境

3 创建根证书CA

4 颁发证书

4.1 在需要证书的服务器上生成签署证书请求

4.2 在根证服务器上颁发证书

5 测试

5.1 读取test.pfx文件

5.2 读取test.cer文件

前言

最近,我被分配了一项任务来完成数字证书管理系统的开发。一开始,我看起来很困惑,因为我以前不知道什么数字证书,这是一个空白,我不知道它是用来做什么的。所以,我努力工作,花了一个下午和晚上来弥补这部分概念知识,原来的数字证书实际上是网站的身份认证。

1 概念

数字证书是经证书授权中心数字签名的文件,包括公钥所有者信息和公钥。最简单的证书包括证书授权中心的公共密钥、名称和数字签名。数字证书的另一个重要特点是只在特定时间内有效。数字证书是一种权威的电子文件,可以由权威公正的第三方组织,即CA(比如中国各地CA公司)中心签发的证书,也可以由企业级CA发布系统。

一般证书分为根证书、服务器证书和客户端证书三类。根证书是生成服务器证书和客户端证书的基础,是信任的来源,也可以称为自签发证书,即CA证书。服务器证书由根证书颁发,并配置在服务器上。客户端证书由根证书颁发,配置在服务器上,并发送给客户,让客户安装在浏览器中。

接下来,在了解了证书的基本概念后,我们将了解公钥/私钥/签名/验证签名/加密/解密/对称加密/非对称加密。

我们通常用密码加密文件,然后用相同的密码解密。很容易理解,这是对称加密。在某些加密过程中,一组密码用于加密,另一组密码用于解密,称为不对称加密,即加密和解密的密码不同。事实上,这是数学中素数积求因子的原理应用。因此,这组密钥中的一个用于加密数据,另一个用于解密。也许有些人已经想到了,是的,这就是所谓的公钥和私钥。公钥和私钥都可以用来加密数据,但区别在于公钥是密钥对中公开的部分,私钥是非公开的部分。公钥加密数据,然后私钥解密称为加密和解密;私钥加密数据,公钥解密一般称为签名和验证签名。签名和验证签名是用签名和验证签名,因为在生成证书的过程中需要签名,而使用证书需要验证签名。

2 环境

需要一个linux系统(一般centos 6以上或debian),一般linux安装了系统openssl的,若没有安装或嫌版本太低可参考

Tomcat集群搭建(nginx tomcat redis)_叶梦_的博客-CSDN博客

本文的linux系统是centos 7,openssl版本是OpenSSL 1.0.2k。是否安装可以通过以下命令来验证。openssl,或者查看当前openssl的版本。

openssl version -a

3 创建根证书CA

(1)查看openssl的配置文件openssl.cnf的存放位置(即openssl安装位置)

openssl version -a

(2)查看openssl的配置文件openssl.cnf,因为配置文件定义了证书的名称和存储位置。

vim /etc/pki/tls/openssl.cnf

每个变量背后都有英文注释。懂英语的人应该很容易理解相应变量的含义。不懂英语的人可以直接在百度上搜索或拿出你的英文翻译器翻译。

(3)创建根证书CA所需的目录和文件

#根据配置文件信息CA如果没有,创建自己的根目录。 cd /etc/pki/CA #在配置文件信息中创建所需的目录和文件 mkdir -pv {certs,crl,newcerts,private} touch {serial,index.txt}

(4)指示证书的开始编号

echo 01 >> serial

5)生成根证的私钥(注:私钥的文件名和存储位置应与配置文件中的设置相匹配)。

(umask 077; openssl genrsa -out private/cakey.pem 2048)

参数说明:

genrsa —产生rsa密钥命令

-aes256—使用AES算法(256位密钥)对生成的私钥进行加密,这里没有此参数,只使用rsa算法加密。

-out —-这里指的是输出路径private/ca.key.pem

这里的参数2048是指密钥的长度位数,默认长度为512位

(6)生成自签证书,即根证书CA,自签证书的存放位置也要与配置文件中的设置相匹配,生成证书时需要填写相应的信息。

openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out cacert.pem -days 365

参数说明:

-new:签署新证书的请求

-x509:专用于CA生成自签证书,如果不是自签证书,证书

-key:使用的私钥文件

-out:保存证书的路径

-days:本单位为证书的有效期day(天),默认是openssl.cnf的default_days

这样,根证书CA已生成完成。

4 颁发证书

在需要证书的服务器上生成私钥,然后通过此私钥生成证书签署请求,最后以可靠的方式将请求发送给根证书CA主机。根证书CA取得证书签署请求后,服务器可颁发服务器证书。

4.1 在需要证书的服务器上生成签署证书请求

(1)生成私钥,私钥的位置可以随意确定

(umask 077; openssl genrsa -out test.key 2048)

参考本文3的(5),具体参数含义。

(2)签署生成证书的请求

openssl req -new -key test.key -out test.csr -days 365

参考本文3的(6),具体参数含义。

4.2 在根证服务器上颁发证书

(1)颁发证书,即签名证书,生成crt文件

#我们创造一个req文件夹接收服务器发送的文件(签署请求csr文件、key文件等) mkdir /etc/pki/CA/req #颁发证书 openssl ca -in /etc/pki/CA/req/test.csr -out /etc/pki/CA/certs/test.crt -days 365 #查看证书信息 openssl x509 -in /etc/pki/CA/certs/test.crt -noout -serial -subject

但有些格式不是我们需要的,请看以下两种格式转换。

(2)格式转换为pfx格式的私钥

openssl pkcs12 -export -out test.pfx -inkey /etc/pki/CA/req/test.key -in test.crt

注意,-inkey的值test.key私钥需要在证书服务器上生成key文件。

(3)格式转换为cer格式的公钥

openssl x509 -inform pem -in test.crt -outform der -out test.cer #查看cer证书信息 openssl x509 -in test.cer -text -noout #若报错unable to load certificate,这意味着你打开的证书编码是der格式需要下列命令 openssl x509 -in test.cer -inform der -text -noout

参数含义:

-inform pem,由于输入的test.crt文件是以pem编码需要指定pem读取编码。

-outform der,输出的test.cer文件需要以der编码。

到目前为止,服务器证书的颁发已经完成,只需将签名证书发送给服务器,服务器就可以使用签名证书。

5 测试

我们此处用java单独读取代码进行测试test.pfx和test.cer文件证书信息。

5.1 读取test.pfx文件

import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.Certificate; import java.util.Enumeraton;
public class ReadPFX {
    public static void main(String[] args) throws Exception {
        String strPfx = "C:\\Users\\admin\\Desktop\\新建文件夹\\test.pfx";
        String strPassword = "123";
        KeyStore ks = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream(strPfx);
        // If the keystore password is empty(""), then we have to set
        // to null, otherwise it won't work!!!
        char[] nPassword = null;
        if ((strPassword == null) || strPassword.trim().equals("")) {
            nPassword = null;
        } else {
            nPassword = strPassword.toCharArray();
        }
        ks.load(fis, nPassword);
        fis.close();
        System.out.println("keystore type=" + ks.getType());
        // Now we loop all the aliases, we need the alias to get keys.
        // It seems that this value is the "Friendly name" field in the
        // detals tab <-- Certificate window <-- view <-- Certificate
        // Button <-- Content tab <-- Internet Options <-- Tools menu
        // In MS IE 6.
        Enumeration enumas = ks.aliases();
        String keyAlias = null;
        if (enumas.hasMoreElements())// we are readin just one certificate.
        {
            keyAlias = (String) enumas.nextElement();
            System.out.println("alias=[" + keyAlias + "]");
        }
        // Now once we know the alias, we could get the keys.
        System.out.println();
        System.out.println("is key entry=" + ks.isKeyEntry(keyAlias));
        PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);
        Certificate cert = ks.getCertificate(keyAlias);
        PublicKey pubkey = cert.getPublicKey();
        System.out.println("cert class = " + cert.getClass().getName());
        System.out.println("cert = " + cert);
        System.out.println("public key = " + pubkey);
        System.out.println("private key = " + prikey);
    }
}

输出结果展示,如下所示:

keystore type=PKCS12
alias=[1]
is key entry=true
cert class = sun.security.x509.X509CertImpl
cert = [
[
  Version: V3
  Subject: EMAILADDRESS=test@test.com, CN=www.test.com, O=sky, ST=GuangDong, C=CN
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
  Key:  Sun RSA public key, 2048 bits
  modulus: 22540549868269337731049045024507385260542573787628838370500488975031456915675928339191598608788978166412886818018144053254194317256993635868534742497106051883418262409480683986537120518762380588035635893822782045653063382717204771221158285234168172584993231255251797413350283828305540028023358503599723497159109886144323832651476034904177315494543160791317342173062905173635050774176310860122833148864737280742410768403748999912660341255531672554245341045495023594325494277633017114644620320127314817425829498919103113286133067466723376087306471415425209209026944245886309051331485179319181933688283658147367854481639
  public exponent: 65537
  Validity: [From: Tue Aug 28 19:59:47 CST 2018,
               To: Wed Aug 28 19:59:47 CST 2019]
  Issuer: EMAILADDRESS=sky@sky.com, CN=localhost, O=sky, L=guangzhou, ST=GuangDong, C=CN
  SerialNumber: [    01]
Certificate Extensions: 4
[1]: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
Extension unknown: DER encoded OCTET string =
0000: 04 1F 16 1D 4F 70 65 6E   53 53 4C 20 47 65 6E 65  ....OpenSSL Gene
0010: 72 61 74 65 64 20 43 65   72 74 69 66 69 63 61 74  rated Certificat
0020: 65                                                 e
[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 5C D9 0C CF D3 B8 76 6D   CA AC B0 79 4E 2B 68 61  \.....vm...yN+ha
0010: 0C 64 89 54                                        .d.T
]
]
[3]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:false
  PathLen: undefined
]
[4]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 77 65 68 2C F7 8C 6A 03   E8 FF 7B BB 62 7C FB 63  weh,..j.....b..c
0010: 90 5C F8 09                                        .\..
]
]
]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 82 BC 07 E9 C5 E1 4A C4   88 AD 48 1C 71 68 0D 0E  ......J...H.qh..
0010: 09 0E 79 1D 86 22 ED 2D   34 AB 89 08 D3 4A E1 C2  ..y..".-4....J..
0020: B9 04 82 BC CC 77 6B 71   87 F5 5F B7 F0 86 B5 D6  .....wkq.._.....
0030: CE 26 61 AC 33 96 F5 25   8A 64 32 75 CA CE E6 D2  .&a.3..%.d2u....
0040: 83 A7 6D 43 21 18 60 0C   F5 A7 2E 60 50 73 1E 26  ..mC!.`....`Ps.&
0050: 5F 89 04 55 E2 79 82 70   6C 36 05 B6 00 7D 6F 04  _..U.y.pl6....o.
0060: D8 75 CB D4 7B D6 0A 56   50 95 4A 8E 72 8D 43 C9  .u.....VP.J.r.C.
0070: 65 32 9F 9D 4A 63 6A 74   31 53 65 AC DF A6 B8 76  e2..Jcjt1Se....v
0080: 1D B3 C9 71 ED 38 77 16   AF 2D BD BB 40 A1 40 90  ...q.8w..-..@.@.
0090: 82 63 41 C7 84 4A 38 51   3E A2 AA 31 B4 5F 60 13  .cA..J8Q>..1._`.
00A0: 8D D4 7E 37 63 AE A7 5C   32 A5 09 18 A8 4D D7 69  ...7c..\2....M.i
00B0: CD 11 DF 17 28 07 3B 2D   CA 76 E0 BA 59 A7 CB DE  ....(.;-.v..Y...
00C0: D8 DF AF 7B 98 1B C9 C5   A8 41 DD 9E FB 1A 51 FE  .........A....Q.
00D0: 8A 72 09 51 D3 45 BE EA   17 36 FD 37 45 59 24 6F  .r.Q.E...6.7EY$o
00E0: AA EB E3 4C 65 04 15 24   30 1C 7C F0 8E F1 24 36  ...Le..$0.....$6
00F0: EE 60 B4 30 EB CD A7 21   3A 3A B5 B3 CF 8E E4 81  .`.0...!::......
]
public key = Sun RSA public key, 2048 bits
  modulus: 22540549868269337731049045024507385260542573787628838370500488975031456915675928339191598608788978166412886818018144053254194317256993635868534742497106051883418262409480683986537120518762380588035635893822782045653063382717204771221158285234168172584993231255251797413350283828305540028023358503599723497159109886144323832651476034904177315494543160791317342173062905173635050774176310860122833148864737280742410768403748999912660341255531672554245341045495023594325494277633017114644620320127314817425829498919103113286133067466723376087306471415425209209026944245886309051331485179319181933688283658147367854481639
  public exponent: 65537
private key = sun.security.rsa.RSAPrivateCrtKeyImpl@ffd98003

5.2 读取test.cer文件

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class ReadCER {
    public static void main(String[] args) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            FileInputStream fileInputStream = new FileInputStream("C:\\Users\\admin\\Desktop\\新建文件夹\\test.cer");
            X509Certificate cer = (X509Certificate)certificateFactory.generateCertificate(fileInputStream);
            fileInputStream.close();
            System.out.println("读取Cer证书信息...");
            System.out.println("cer_序列号___:"+cer.getSerialNumber());
            System.out.println("cer_发布方标识名___:"+cer.getIssuerDN().getName()); 
            System.out.println("cer_主体标识___:"+cer.getSubjectDN());
            System.out.println("cer_证书算法OID字符串___:"+cer.getSigAlgOID());
            System.out.println("cer_证书有效期___:" + cer.getNotBefore() + "~" + cer.getNotAfter());
            System.out.println("cer_签名算法___:"+cer.getSigAlgName());
            System.out.println("cer_版本号___:"+cer.getVersion());
            System.out.println("cer_公钥___:"+cer.getPublicKey());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果展示,如下所示:

读取Cer证书信息...
cer_序列号___:1
cer_发布方标识名___:EMAILADDRESS=sky@sky.com, CN=localhost, O=sky, L=guangzhou, ST=GuangDong, C=CN
cer_主体标识___:EMAILADDRESS=test@test.com, CN=www.test.com, O=sky, ST=GuangDong, C=CN
cer_证书算法OID字符串___:1.2.840.113549.1.1.11
cer_证书有效期___:Tue Aug 28 19:59:47 CST 2018~Wed Aug 28 19:59:47 CST 2019
cer_签名算法___:SHA256withRSA
cer_版本号___:3
cer_公钥___:Sun RSA public key, 2048 bits
  modulus: 22540549868269337731049045024507385260542573787628838370500488975031456915675928339191598608788978166412886818018144053254194317256993635868534742497106051883418262409480683986537120518762380588035635893822782045653063382717204771221158285234168172584993231255251797413350283828305540028023358503599723497159109886144323832651476034904177315494543160791317342173062905173635050774176310860122833148864737280742410768403748999912660341255531672554245341045495023594325494277633017114644620320127314817425829498919103113286133067466723376087306471415425209209026944245886309051331485179319181933688283658147367854481639
  public exponent: 65537

读取证书信息成功,测试完成,收工!

标签: weh快速连接器tvr60

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台