使用 openssl 制作证书


原文链接: 使用 openssl 制作证书

Chapter 7 OpenSSL
OpenSSL 生成根证书 CA 及签发子证书

那些证书相关的玩意儿 (SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12 等)

数字证书及 CA 的扫盲介绍 @ 编程随想的博客
数字签名与数字证书 - oscar999 的专栏 - 博客频道 - CSDN.NET
数字签名原理简介(附数字证书) - kingsleylam - 博客园

生成随机数

openssl rand -base64 128

字符串加解密

echo "message" | openssl enc -aes-256-cbc -a -pass pass:$password
echo "encmessage" | openssl enc -aes-256-cbc -a -d -pass pass:$password

文件加密AES

-binary
-nopad -nosalt
bad decrypt
windows加密Linux解密错误处理: envelope routines:EVP_EncryptFinal_ex:data not multiple of block length:evp_enc.c:414 只在Linux解密时 增加 -nopad 参数

openssl aes-256-cbc -e -md md5 -pass "pass:Hr2019" -in lzkp_bi.zip -out a.zip.gpg # 密码加密
openssl aes-256-cbc -d -md md5 -pass "pass:Hr2019" -in a.txt.gpg -out aa.txt # 密码解密

openssl enc -e -aes-256-cbc -pass pass:'123456' -in a.txt -out a.txt.gpg # 密码加密 openssl enc -d -aes-256-cbc -pass pass:'123456' -in a.txt.gpg -out aa.txt # 密码解密

openssl aes-256-cbc -md md5 -k 'lzkp' -in a.txt -out a.txt.gpg
openssl aes-256-cbc -md md5 -e -k '123456' -in a.txt -out a.txt.gpg
openssl aes-256-cbc -md md5 -nopad -d -k '123456' -in a.txt.gpg -out aa.txt

加密参数:
-salt 是否加盐,加密 -e 时使用
-k "123456" =不等价= -pass pass:'123456'
-kfile "pass.pem" =等价= -pass file:'./pass.pem'
-md md5|SHA256 指定hash算法 use to create a key from a passphrase.
-a -base64 对输出文件进行 base64 编码输出

CBC模式下的Blowfish

要加密:

$ openssl bf < arquivo.txt > arquivo.txt.bf
要解密:

$ openssl bf -d < arquivo.txt.bf > arquivo.txt
bf === CBC模式下的Blowfish

cipher suites

密码套件(Cipher suite)是传输层安全(TLS)/安全套接字层(SSL)网络协议中的一个概念。
在TLS 1.3之前,密码套件的名称是以协商安全设置时使用的身份验证、加密、消息认证码(MAC)和密钥交换算法组成。TLS 1.3中的密码套件格式已经修改。在目前的TLS 1.3草案文档中,密码套件仅用于协商加密和HMAC算法。[1]

每个cipher suite(例如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)定义一个密钥交换算法、一个批量加密算法、一个消息认证码(MAC)算法,以及一个伪随机函数(PRF)。

密钥交换算法,例如ECDHE_RSA,用于决定客户端与服务器之间在握手时如何身份验证。[8]
批量加密算法,例如AES_128_GCM,用于加密消息流。它还包括密钥大小及显式和隐式初始化向量(密码学随机数)的长度。[9]
消息认证码算法,例如SHA256,用于创建消息摘要,消息流每个数据块的加密散列。[9]
伪随机函数,例如TLS 1.2的伪随机函数使用MAC算法的散列函数来创建一个主密钥——连接双方共享的一个48字节的私钥。主密钥在创建会话密钥(例如创建MAC)时作为一个熵来源。[10]

算法示例

  1. 密钥交换/协商
    RSA、Diffie–Hellman、ECDH、SRP、PSK
  2. 身份验证
    RSA、DSA、ECDSA
  3. 块密码
    RC4、3DES、AES、IDEA、DES、Camellia。在旧版本的SSL中,RC2也被使用过。
  4. 消息身份验证
    对于TLS来说,密钥散列消息认证码使用MD5或一种SHA散列算法。对于SSL,则SHA、MD5、MD4及MD2都可使用。

  • 对称加密
    AES(128) | DES(64) | Blowfish(64) | CAST(64) | IDEA(64) | RC2(64) | RC5(64)
  • 非对称加密
    DH | RSA | DSA | EC
  • 信息摘要 hash
    MD2 | MD5 | MDC2 | SHA | RIPEMD | DSS

1. [公钥加密] 无密码加密传输

公钥加密
这是并不能确保文件是不是被其他人篡改过了,因为任何人都可以拿到 B 的公钥

2. [公钥加密+数字签名] 解决源文件被修改的问题

非对称加密

3. [公钥加密+数字签名+对称加密] 解决公钥加密速度慢的问题

  1. B 的公钥加密 AES 密钥(加密密码) B 的私钥解密 对称密钥(解密密码)
  2. 用 AES 密钥加密原文(密码) (解密)
  3. A 的私钥加密 摘要 (数字签名) A 的公钥解密 HASH
    对称加密

当 A 使用 B 的公钥对 AES 密钥进行加密时,如何确定 B 的公钥就是正确的呢?

4. [证书 + 数字签名 + 对称加密] 解决信任问题

用 CA 的公钥解开数字证书,就可以拿到 B 真实的公钥了,然后就能证明 "数字签名" 是否真的是鲍勃签的

消息摘要与MAC的区别,消息摘要只能保证消息的完整性,MAC不仅能够保证完整性,还能够保证真实性
MAC不能保证消息的不可抵赖性,而数字签名可以保证。因为数字签名使用的是公钥密码体制,私钥只有你自己才知道;而MAC使用对称加密,既然一方能够验证你的MAC,就能够伪造你的MAC,因为发送方和接收方的秘钥是一样的。当然如果你在MAC中绑定一些关键信息,并通过某些手段,让一方只能生成MAC,另一方只能验证MAC,其实也是可以实现签名效果的。

1. 摘要算法HASH - 确保得到的数据完整可靠,没有被篡改的。

数字摘要是采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。“数字摘要“是https能确保数据完整性和防篡改的根本原因。

消息认证码算法 HMAC - 不仅能够保证完整性,还能够保证真实性

消息摘要与MAC的区别,消息摘要只能保证消息的完整性,MAC不仅能够保证完整性,还能够保证真实性
比如客户端A想给服务端B发送一条消息,A需要把消息内容和对应的消息摘要都发给B;B通过同样的摘要算法,自然可以知道消息是否被篡改。比如攻击者C将A发送的原始消息和摘要,都篡改成新的消息和摘要,那么这个消息对B来说也是完整的,只不过不是A发的。因为MAC含有秘钥(只有A和B知道),如果A将消息内容和MAC发给B,虽然C是仍然可以修改消息内容和MAC,但是由于C不知道秘钥,所以无法生成与篡改后内容匹配的MAC。

数字签名 - 确保信息的摘要是发送者生成的,而不是其他人伪造的。

MAC不能保证消息的不可抵赖性,而数字签名可以保证。因为数字签名使用的是公钥密码体制,私钥只有你自己才知道;而MAC使用对称加密,既然一方能够验证你的MAC,就能够伪造你的MAC,因为发送方和接收方的秘钥是一样的。当然如果你在MAC中绑定一些关键信息,并通过某些手段,让一方只能生成MAC,另一方只能验证MAC,其实也是可以实现签名效果的。
数字签名 发送者将信息哈希后用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
数字签名的过程如下:
明文 --> hash运算 --> 摘要 --> 私钥加密摘要 --> 数字签名

数字签名有两种功效:
一、能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
二、数字签名能确定消息的完整性。

注意:
数字签名只能验证数据的完整性,数据本身是否加密不属于数字签名的控制范围

数字证书 - 确保 数字签名的公钥 是可信的

为什么要有数字证书?

对于请求方来说,它怎么能确定它所得到的公钥一定是从目标主机那里发布的,而且没有被篡改过呢?亦或者请求的目标主机本本身就从事窃取用户信息的不正当行为呢?这时候,我们需要有一个权威的值得信赖的第三方机构(一般是由政府审核并授权的机构)来统一对外发放主机机构的公钥,只要请求方这种机构获取公钥,就避免了上述问题的发生。
数字证书的颁发过程

用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息(根证书私钥签名)。用户就可以使用自己的数字证书进行相关的各种活动。数字证书由独立的证书发行机构发布,数字证书各不相同,每种证书可提供不同级别的可信度。
证书包含哪些内容

证书颁发机构的名称
证书本身的数字签名
证书持有者公钥
证书签名用到的Hash算法

验证证书的有效性

浏览器默认都会内置CA根证书,其中根证书包含了CA的公钥

证书颁发的机构是伪造的:浏览器不认识,直接认为是危险证书
证书颁发的机构是确实存在的,于是根据CA名,找到对应内置的CA根证书、CA的公钥。用CA的公钥,对伪造的证书的摘要进行解密,发现解不了,认为是危险证书。
对于篡改的证书,使用CA的公钥对数字签名进行解密得到摘要A,然后再根据签名的Hash算法计算出证书的摘要B,对比A与B,若相等则正常,若不相等则是被篡改过的。
证书可在其过期前被吊销,通常情况是该证书的私钥已经失密。较新的浏览器如Chrome、Firefox、Opera和Internet Explorer都实现了在线证书状态协议(OCSP)以排除这种情形:浏览器将网站提供的证书的序列号通过OCSP发送给证书颁发机构,后者会告诉浏览器证书是否还是有效的。

1、2点是对伪造证书进行的,3是对于篡改后的证书验证,4是对于过期失效的验证。

HMAC (keyed-Hash Message Authentication Code,消息认证码算法)是含有密钥的散列函数算法

HMAC算法的实现过程需要一个散列函数(表示为H,Md5或者SHA)和一个密钥。
用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输
在实践中它应该是这么用的:

  //sha256
	h := sha256.New()
	io.WriteString(h, "aaaaaa")
	fmt.Printf("%x\n", h.Sum(nil))

	//hmac ,use sha1
	key := []byte("passwdkey")
	mac := hmac.New(sha1.New, key)
	mac.Write([]byte("aaaaaa"))
  fmt.Printf("%x\n", mac.Sum(nil))  

(1)客户端向服务器发起请求,访问登录页面.
(2)这时服务器生成一个随机密钥,把这个随机密钥存储在服务端session之中,然后将随机密钥返回给客户端.
(3)客户端填写登录表单,经过HMAC算法和收到的随机密钥,将用户信息加密后post到服务器.
(4)服务器读取数据库中的密码,用HMAC将密码和session中的密钥进行加密产生密码的密文,将密文与用户提交的进行比较.

HMAC_MD5("", "") = 74e6f7298a9c2d168935f58c001bad88
HMAC_SHA1("", "") = fbdb1d1b18aa6c08324b7d64b71fb76370690e1d
HMAC_SHA256("", "") = b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad

证书格式转换

一些概念
数字证书: 证书是为了让客户端确认一个我拿到的这个公钥就是服务器(google)的,而不是别人伪造的
KEY : 私钥文件,决定 ssl 安全的基础
CSR : Certificate Signing Request 证书请求文件,包含公钥和证书信息
CA : 中级证书颁发机构,一般是可信的第三方,CA 证书会验证公钥是否被认证
root CA:通过它的私钥对中级机构提交的 CSR 进行了签名

申请 ssl 证书需要用到 openssl,linux 系统中默认会安装,手动安装 openssl:
yum install -y openssl openssl-devel

配置 /etc/ssl/openssl.cnf

CA 密钥公钥

[ CA_default ]

dir           = /etc/pki/CA                // 工作目录
certs         = $dir/certs                 // 客户端证书保存目录
crl_dir       = $dir/crl                   // 证书吊销列表的位置
database      = $dir/index.txt             // 证书发证记录数据库
new_certs_dir = $dir/newcerts              // 新生成证书存放目录
certificate   = $dir/cacert.pem            // CA的证书文件
serial        = $dir/serial                // 签发证书的序列号,一般从01开始
crlnumber     = $dir/crlnumber             // 帧数吊销列表的序列号
crl           = $dir/crl.pem               // 证书吊销列表文件
private_key   = $dir/private/cakey.pem     // CA的私钥文件
RANDFILE      = $dir/private/.rand         // 随机数生产文件,会自动创建
default_days  = 365                        // 默认签发有效期

一. 生成私钥.key

私钥是 SSL 安全性的基础,使用 RSA 算法生成,只有证书申请者持有,即使 CA 也没有对私钥的访问权限,应妥善保管。私钥长度决定其安全性,2009 年 768 位 RSA 已被破解,1024 位 RSA 短期内是安全的,但随着计算机越来越快,已不足以抵御攻击,为了安全起见应尽量使用 2048 位 RSA,生成 2048 位私钥:
openssl genrsa -out 52os.net.key 2048

如果对安全性要求较高,可以用密码加密密钥文件,每次读取密钥都需输入密码:
openssl genrsa -des3 -out 52os.net.key 2048

如何去除私钥密码保护

如果您的密钥已经加载密码保护,可以通过 OpenSSL 工具 运行以下命令去掉密码保护:
openssl rsa -in encryedprivate.key -out unencryed.key

encryedprivate.key 是带密码保护的私钥文件。
unencryed.key 是去掉了密码的私钥文件,扩展名为 key 或者 pem 均可。

### 二. 生成 CSR 【B 的公钥】

证书签名请求文件(CSR)中包含了公钥和证书的详细信息,将 CSR 发送给 CA 认证后就会得到数字证书或证书链,生成 CSR 文件:

openssl req -new -sha256 -key 52os.net.key -out 52os.net.csr
按照提示输入:国家、省份、城市、组织名、部门、公共名称、邮件地址等,最后的 extra 信息不要填写,个人用户也可以使用默认或留空,只需注意‘Common Name’是要使用 ssl 证书的域名,根据实际情况,可以写单域名,多个域名,或使用 * 通配域名
验证 CSR 文件信息:

openssl req -noout -text -in 52os.net.csr
确认信息正确就可以提交给 ca 进行认证,CA 会根据你的 CSR 文件进行签名,之后颁发数字证书,该数字证书和私钥就可以部署到服务器了;通常 ca 认证需付费,普通 ssl 证书不贵,也有一些提供免费的证书的 ca,如 startssl、Let's Encrypt 等

如何制作阿里云 CSR 文件?

三. 自签名
在某些情况下,如内网 https 的应用,不需要付费使用第三方签名,此时就可以使用自签名证书。自签名分两种:
使用自己的私钥签发自己的 csr 生成证书,也可以直接生成私钥和证书
生成 ca,使用 ca 签发
生成 ca 的好处是:客户只要手动信任该 ca 一次,即可信任该 ca 签发的所有证书,不需要为每个证书添加信任

3.1 使用自签名
使用上面生成的私钥签发证书:
openssl x509 -req -days 365 -in 52os.net.csr -extensions v3_ca -signkey 52os.net.key -out 52os.net365.crt
或者直接生成私钥和证书:
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout 52os.net.key -out 52os.net.crt
可以使用 chrome 浏览器导出证书并安装到 windows 信任证书中,安装后浏览器地址栏的 https 就会变成绿色。导出方法:访问 https 网站,点击地址栏上有红色叉的锁型图标,点击详细信息,点击查看证书,在弹出的证书窗口中点击详细信息选项卡,点击复制到文件,之后按证书导出向导的提示即可导出

3.2 使用 ca 签名

生成 CA:
openssl genrsa -out CA.key 2048
openssl req -new -x509 -key CA.key -out CA.cer -days 36500 -subj /CN='52os CA'
使用 ca 签发证书:
openssl x509 -req -in 52os.net.csr -extensions v3_usr -CA CA.cer -CAkey CA.key -CAcreateserial -out 52os.net.crt
为了更好的兼容浏览器,还需:

cat CA.cer >> 52os.net.crt
客户端手动信任 CA.cer 即可,windows 下可以双击安装

参考文章:
http://www.51ean.com/interaction/safety_information_details.html?postId=585
http://blog.csdn.net/tenfyguo/article/details/40922813
http://www.wosign.com/Basic/index.htm
http://www.cnblogs.com/kyrios/p/tls-and-certificates.html

HTTPS:

  1. server 生成 crt.pub
  2. client 生成 random + key server 生成对称密钥
  3. 通过对称密钥加密

之前没接触过证书加密的话, 对证书相关的这些概念真是感觉挺棘手的, 因为一下子来了一大堆新名词, 看起来像是另一个领域的东西, 而不是我们所熟悉的编程领域的那些东西, 起码我个人感觉如此, 且很长时间都没怎么搞懂. 写这篇文章的目的就是为了理理清这些概念, 搞清楚它们的含义及关联, 还有一些基本操作.

SSL

SSL - Secure Sockets Layer, 现在应该叫 "TLS", 但由于习惯问题, 我们还是叫 "SSL" 比较多. http 协议默认情况下是不加密内容的, 这样就很可能在内容传播的时候被别人监听到, 对于安全性要求较高的场合, 必须要加密, https 就是带加密的 http 协议, 而 https 的加密是基于 SSL 的, 它执行的是一个比较下层的加密, 也就是说, 在加密前, 你的服务器程序在干嘛, 加密后也一样在干嘛, 不用动, 这个加密对用户和开发者来说都是透明的. More:[维基百科]

OpenSSL - 简单地说, OpenSSL 是 SSL 的一个实现, SSL 只是一种规范. 理论上来说, SSL 这种规范是安全的, 目前的技术水平很难破解, 但 SSL 的实现就可能有些漏洞, 如著名的 "心脏出血".OpenSSL 还提供了一大堆强大的工具软件, 强大到 90% 我们都用不到.

证书标准

X.509 - 这是一种证书标准, 主要定义了证书中应该包含哪些内容. 其详情可以参考 RFC5280,SSL 使用的就是这种证书标准.
编码格式
同样的 X.509 证书, 可能有不同的编码格式, 目前有以下两种编码格式.

编码格式

  1. 文本格式 PEM - Privacy Enhanced Mail, 打开看文本格式, 以 "-----BEGIN..." 开头, "-----END..." 结尾, 内容是 BASE64 编码.
    查看 PEM 格式证书的信息: openssl x509 -in certificate.pem -text -noout
    Apache 和 * NIX 服务器偏向于使用这种编码格式.

  2. 二进制格式 DER - Distinguished Encoding Rules, 打开看是二进制格式, 不可读.
    查看 DER 格式证书的信息: openssl x509 -in certificate.der -inform der -text -noout
    Java 和 Windows 服务器偏向于使用这种编码格式.

    文件扩展名

这是比较误导人的地方, 虽然我们已经知道有 PEM 和 DER 这两种编码格式, 但文件扩展名并不一定就叫 "PEM" 或者 "DER", 常见的扩展名除了 PEM 和 DER 还有以下这些, 它们除了编码格式可能不同之外, 内容也有差别, 但大多数都能相互转换编码格式.

  1. CRT - CRT 应该是 certificate 的三个字母, 其实还是证书的意思, 常见于 * NIX 系统, 有可能是 PEM 编码, 也有可能是 DER 编码, 大多数应该是 PEM 编码, 相信你已经知道怎么辨别.

  2. CER - 还是 certificate, 还是证书, 常见于 Windows 系统, 同样的, 可能是 PEM 编码, 也可能是 DER 编码, 大多数应该是 DER 编码.

  3. KEY - 通常用来存放一个公钥或者私钥, 并非 X.509 证书, 编码同样的, 可能是 PEM, 也可能是 DER.
    查看 KEY 的办法: openssl rsa -in id_rsa.key -text -noout
    如果是 DER 格式: openssl rsa -in mykey.key -text -noout -inform der

  4. CSR - Certificate Signing Request, 即证书签名请求, 这个并不是证书, 而是向权威证书颁发机构获得签名证书的申请, 其核心内容是一个公钥 (当然还附带了一些别的信息), 在生成这个申请的时候, 同时也会生成一个私钥, 私钥要自己保管好. 做过 iOS APP 的朋友都应该知道是怎么向苹果申请开发者证书的吧.
    查看的办法: openssl req -noout -text -in my.csr (如果是 DER 格式的话照旧加上 - inform der, 这里不写了)

  5. PFX/P12 - predecessor of PKCS#12, 对 * nix 服务器来说, 一般 CRT 和 KEY 是分开存放在不同文件中的, 但 Windows 的 IIS 则将它们存在一个 PFX 文件中,(因此这个文件包含了证书及私钥) 这样会不会不安全?应该不会, PFX 通常会有一个 "提取密码", 你想把里面的东西读取出来的话, 它就要求你提供提取密码, PFX 使用的时 DER 编码,
    如何把 PFX 转换为 PEM 编码? openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
    这个时候会提示你输入提取代码. for-iis.pem 就是可读的文本.
    生成 pfx 的命令类似这样: openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt

其中 CACert.crt 是 CA(权威证书颁发机构) 的根证书, 有的话也通过 - certfile 参数一起带进去. 这么看来, PFX 其实是个证书密钥库.

  1. JKS - 即 Java Key Storage, 这是 Java 的专利, 跟 OpenSSL 关系不大, 利用 Java 的一个叫 "keytool" 的工具, 可以将 PFX 转为 JKS, 当然了, keytool 也能直接生成 JKS, 不过在此就不多表了.

证书编码的转换

PEM 转为 DER openssl x509 -in cert.crt -outform der -out cert.der

DER 转为 PEM openssl x509 -in cert.crt o pinform der -outform pem -out cert.pem

(提示: 要转换 KEY 文件也类似, 只不过把 x509 换成 rsa, 要转 CSR 的话, 把 x509 换成 req...)
获得证书

向 CA 权威证书颁发机构申请证书 CSR

用这命令生成一个 csr: openssl req -newkey rsa:2048 -new -nodes -keyout my.key -out my.csr
把 csr 交给权威证书颁发机构, 权威证书颁发机构对此进行签名, 完成. 保留好 csr, 当权威证书颁发机构颁发的证书过期的时候, 你还可以用同样的 csr 来申请新的证书, key 保持不变.

或者生成自签名的证书
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
在生成证书的过程中会要你填一堆的东西, 其实真正要填的只有 Common Name, 通常填写你服务器的域名, 如 "yourcompany.com", 或者你服务器的 IP 地址, 其它都可以留空的.
生产环境中还是不要使用自签的证书, 否则浏览器会不认, 或者如果你是企业应用的话能够强制让用户的浏览器接受你的自签证书也行. 向权威机构要证书通常是要钱的, 但现在也有免费的, 仅仅需要一个简单的域名验证即可. 有兴趣的话查查 "沃通数字证书".
#####################

生成证书请求文件

2.1 生成 csr 请求文件
2.1.2 生成 key 私钥文件
使用以下命令来生成私钥:openssl genrsa -des3 -out www.deedbeef.com.key 2048,生成的私钥保存在当期目录。
2.1.3 生成 [根证书]csr 文件
使用以下命令来生成私钥:openssl req -new -key www.mydomain.com.key -out www.mydomain.com.csr

Country Name (2 letter code) [GB]: 输入国家地区代码,如中国的 CN
State or Province Name (full name) [Berkshire]: 地区省份
Locality Name (eg, city) [Newbury]: 城市名称
Organization Name (eg, company) [My Company Ltd]: 公司名称
Organizational Unit Name (eg, section) []: 部门名称
Common Name (eg, your name or your server’s hostname) []: 申请证书域名
Email Address []: 电子邮箱
随后可能会提示输入密码,一般无需输入,直接回车即可

之前申请的 StartSSL 免费一年的证书到期了,考虑到我对 SSL 一般仅用于博客登录和后台管理上面,所以不打算续申请,自己创建一个就足够了。
本来想使用 Windows 下的 makecert 实用工具创建的,结果折腾了很久导入到 Linux 服务器上,服务器没有正确识别,遂放弃,转而使用 OpenSSL,收集了网上的一些材料,通过下面的方法创建成功:

数字证书:

证书是持有者的详细信息,证书有公钥。包括名称、公钥信息等; 针对证书的防伪信息叫做签名。

数字签名:

签名是使用个人私密和加密算法加密的摘要和报文,是私人性的。而数字证书是由 CA 中心派发的.

1)CA:签证机构 (签发证书的机构) 功用:保证公钥信息安全分发;
2)数字证书的格式 (x.509 v3):

   版本号(version)
   序列号 (serial number):CA 用于惟一标识此证书;
   签名算法标志 (Signature algorithm identifier)
   发行者的名称:即 CA 自己的名称;
   有效期:两个日期,起始日期和终止日期;
   证书主体名称:证书拥有者自己的名字
   证书主体公钥信息:证书拥有者自己的公钥;
    发行商的惟一标识:  CA 标识号
    证书主体的惟一标识:
    扩展信息:
    签名:CA 对此证书的数字签名;(防伪信息)
  1. 签发机构名 (Issuer)
    此域用来标识签发证书的 CA 的 X.500 DN(DN-Distinguished Name) 名字。包括:
    1) 国家 (C) Country Name (2 letter code) [CN]
    2) 省市 (ST) State or Province Name (full name) [shandong]
    3) 地区 (L) Locality Name (eg, city) [linyi]
    4) 组织机构 (O) Organization Name (eg, company) [Company Ltd]
    5) 单位部门 (OU) Organizational Unit Name (eg, section) [system]
    6) 通用名 (CN) Common Name (eg, your name or your server’s hostname) [kbook.org]
    7) 邮箱地址

    mitmproxy-ca.pem 私钥 + 证书 文本格式
    mitmproxy-ca-cert.pem Unix 平台使用证书 (certificate) 格式 文本格式
    mitmproxy-ca-cert.cer 与 mitmproxy-ca-cert.pem 相同,android 上使用证书 (certificate) 格式 文本格式
    mitmproxy-ca-cert.p12 windows 上使用证书 (certificate) 格式 文本格式
    

    为了安全起见,修改 cakey.pem 私钥文件权限为 600 或 400,也可以使用子 shell 生成 ( umask 077);
    一、证书制作

    1、制作 CA 证书:

  2. 制作 根证书 CA 的私匙 CA.key (私钥):
    openssl genrsa -out ca.key 2048 ``
    网上很多是使用了 1024,我这里强度加强到了 2048。

  3. 制作解密后的 CA 私钥(一般无此必要):
    此步骤可以跳过 openssl rsa -in ca.key -out ca_decrypted.key

  4. 利用 ca.key 私钥 创建根证书 ca.crt (公钥):
    openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj \ "/C=CN/ST=Shandong/L=Linyi/O=pytool/OU=Symantec Corporation"
    openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj \ "/C=CN/ST=Jiangsu/L=Yangzhou/O=Your Company Name/OU=Your Root CA"
    -new: 生成新的证书签署请求;
    -key:私钥文件路径,用于提取公钥;
    -days N: 证书有效时长,单位为 “天”;
    -out:输出文件保存位置;
    -x509:直接输出自签署的证书文件,通常只有构建 CA 时才这么用;
    这里 / C 表示国家 (Country),只能是国家字母缩写,如 CN、US 等;/ST 表示州或者省 (State/Provice);/L 表示城市或者地区 (Locality);/O 表示组织名 (Organization Name);/OU 其他显示内容,一般会显示在颁发者这栏。

到这里根证书就已经创建完毕了,

2、制作生成网站的证书并用 CA 签名认证

下面介绍建立网站 SSL 证书的步骤: 假设网站域名为 pytool.cn

  1. 创建 SSL 证书 (私匙)
    openssl genrsa -out server.key 2048 openssl genrsa -des3 -out pytool.pem 2048
  2. 制作解密后的证书私钥:
    此步骤可以跳过:openssl rsa -in pytool.pem -out pytool.key
  3. 生成签名请求CSR:利用刚才的私匙建立 SSL 证书:
    openssl req -new -key server.key -out server.csr -subj \ "/C=CN/ST=Jiangsu/L=Yangzhou/O=Your Company Name/OU=wangye.org/CN=wangye.org"

openssl req -new -key server.key -out server.csr -subj \ "/C=CN/ST=beijing/L=haidian/O=pytool/OU=pytool.com/CN=pytool.com"

这里需要注意的是后三项,
/O 组织字段内容必须与刚才的 CA 根证书相同,用公司名;
/OU 单位部门字段最好也为网站域名,当然选择其他名字也没关系。
/CN 通用名字段为 (Common Name),必须为网站的域名 (不带 www,也可以使用泛域名*.);
/CN 也可以使用泛域名如 *.pytool.com 来生成所有二级域名可用的网站证书。

备注: CSR(证书签名请求,你需要发送给 CA,等待 CA 批准)
openssl req -sha256 -new -key server.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey server.pem -out my-certificate.pem

备注:用一行命令同时生成一对密钥 + 证书 `openssl req -nodes -new -x509 -keyout server.key -out server.cert`
  1. 做些准备工作:

    mkdir demoCA
    cd demoCA
    mkdir newcerts
    touch index.txt
    echo '01' > serial
    cd ..
    

    注意 cd ..,利用 ls 命令检查一下是不是有个 demoCA 的目录。

  2. 用 CA 根证书签署 SSL 自建证书 :
    openssl ca -cert ca.crt -keyfile ca.key -in server.csr -out server.crt
    openssl ca -days 1460 -cert ca.crt -keyfile ca.key -in server.csr -out server.crt

  3. 最后,把 ca.crt 的内容粘贴到 server.crt 后面。这个比较重要!因为不这样做,可能会有某些浏览器不支持

接下来有一段提示,找到 Sign the certificate? [y/n] 这句,打入 y 并回车,然后出现 out of 1 certificate requests certified, commit? [y/n],同样 y 回车。
好了,现在目录下有两个服务器需要的 SSL 证书及相关文件了,分别是 server.crt 和 server.key,接下来就可以利用它们配置你的服务器软件了。
需要注意的是由于是自签名证书,所以客户端需要安装根证书,将刚才第 2 步创建的根证书 ca.crt 下载到客户端,然后双击导入,否则会提示不受信任的证书发布商问题。
通常情况下私人或者内部用的话,自建证书已经绰绰有余了,但是如果你的产品面向的是大众,那就花点银子去买正规的 SSL 证书吧,可不能学某售票系统强制要求安装自建的根证书哦。

ca.key      CA 私钥
ca.crt      CA 私钥 -> CA 证书                      [客户端安装 ca.crt]
server.key  网站私钥                                [服务端 ssl_certificate_key  /etc/nginx/server.key;]
server.csr  网站 SSL 私钥 -> SSL 证书               [用于生成 server.crt]
server.crt  SSL 证书 + CA 证书 + CA 私钥 -> 网站证书  [服务端 ssl_certificate      /etc/nginx/server.crt;]

证书格式转换:

#IE 浏览器需要 p12 证书,所以需要签发 p12 证书,用于 IE 签发:
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

#IOS 证书签发格式
openssl x509 -in client.crt -out client.cer

#Android 证书签发格式
openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx

#pem 格式证书
openssl pkcs12 -export -in ddmdd_a.pfx -out client.pem

删除私钥密码

openssl rsa -in client.key -out client_open.key

证书撤销:

echo 01 > crlnumber
openssl ca -keyfile ca.key -cert ca.crt -revoke client.crt #从 CA 中撤销证书 client.crt
openssl ca -gencrl -keyfile ca.key -cert ca.crt -out client.crl #生成或更新撤销列表

查看证书信息:
openssl x509 -in client.pem -noout -text

client 浏览器需要使用的文件: ca.crt,client.crt,client.key,client.pfx

server 端使用的文件有: ca.crt, server.crt,server.key

  1. 配置 Nginx SSL

server {

  listen          443 ssl;
  server_name     smsapi.chunbo.com;
  root            /var/www/smsapi.david.com;

  ssl on;
  ssl_certificate         /etc/nginx/conf.d/server.crt;
  ssl_certificate_key     /etc/nginx/conf.d/server.key;
  ssl_client_certificate  /etc/nginx/conf.d/ca.crt;

  ssl_verify_client       off;
  ssl_session_timeout     5m;
  ssl_protocols   SSLv2 SSLv3 TLSv1;
  ssl_ciphers     HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers   on;

  location / {
      index index.php index.html;
  }

  location ~ \.php$ {
      include         /etc/nginx/fastcgi_params;
      if (-f $request_filename) {
          fastcgi_pass   127.0.0.1:9000;
      }
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  }

}

错误处理

index.txt
另外,如果要清空 index.txt 的话,一定要清空到字节 0,里面有一个字节都会导致 openssl ca 错误:
wrong number of fields on line 1 (looking for field 6, got 1, '' left)

################################################################################

7.1. openssl 命令参数
7.1.1. 测试加密算法的速度

$ openssl speed
$ openssl speed rsa
$ openssl speed aes

7.1.2. req

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

7.1.3. x509

openssl x509 -req -in client-req.csr -out client.crt -signkey client-key.pem -CA ca.crt -CAkey ca.key -days 365 -CAserial serial
验证一下我们生成的文件。
openssl x509 -in cacert.pem -text -noout
-extfile
openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca -signkey key.pem -out cacert.pem

7.1.4. ca

生成 CRL 列表

$ openssl ca -gencrl -out exampleca.crl

7.1.5. crl

查看 CRL 列表信息

$ openssl crl -in exampleca.crl -text -noout

验证 CRL 列表签名信息

$ openssl crl -in exampleca.crl -noout -CAfile cacert.pem

7.1.6. pkcs12

-clcerts 表示仅导出客户证书。
openssl pkcs12 -export -clcerts -in 324.cer -inkey ca.pem -out 324.p12 -name "Email SMIME"
转换 PEM 证书文件和私钥到 PKCS#12 文件
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

7.1.13. -config 指定配置文件

openssl req -new -newkey rsa:2048 -config openssl.cfg -keyout server.key -nodes -out certreq.csr

7.1.14. -subj 指定参数

openssl req -new -newkey rsa:2048 -keyout server.key -nodes -subj /C=CN/O=example.com/OU=IT/CN=Neo/ST=GD/L=Shenzhen -out certreq.csr

生成随机数
openssl rand 12 -base64
#SSLsplit
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt

修改 OpenSSL 的配置
安装好之后,定位一下 OpenSSL 的配置文件 openssl.cnf:
locate openssl.cnf
/etc/ssl/openssl.cnf
/usr/lib/ssl/openssl.cnf
certs——存放已颁发的证书
newcerts——存放 CA 指令生成的新证书
private——存放私钥
crl——存放已吊销的整数
index.txt——OpenSSL 定义的已签发证书的文本数据库文件,这个文件通常在初始化的时候是空的
serial——证书签发时使用的序列号参考文件,该文件的序列号是以 16 进制格式进行存放的,该文件必须提供并且包含一个有效的序列号

生成证书之前,需要先生成一个随机数:

openssl rand -out private/.rand 1000
rand——生成随机数
-out——指定输出文件
1000——指定随机数长度

生成根证书

a). 生成根证书私钥 (pem 文件)

OpenSSL 通常使用 PEM(Privacy Enbanced Mail)格式来保存私钥,构建私钥的命令如下:
openssl genrsa -aes256 -out private/cakey.pem 1024
该命含义如下:
genrsa——使用 RSA 算法产生私钥
-aes256——使用 256 位密钥的 AES 算法对私钥进行加密
-out——输出文件的路径
1024——指定私钥长度

b). 生成根证书签发申请文件 (csr 文件)

使用上一步生成的私钥 (pem 文件),生成证书请求文件 (csr 文件):
openssl req -new -key private/cakey.pem -out private/ca.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname"
该命令含义如下:
req——执行证书签发命令
-new——新证书签发请求
-key——指定私钥路径
-out——输出的 csr 文件的路径
-subj——证书相关的用户信息 (subject 的缩写)

c). 自签发根证书 (cer 文件)

csr 文件生成以后,可以将其发送给 CA 认证机构进行签发,当然,这里我们使用 OpenSSL 对该证书进行自签发:
openssl x509 -req -days 365 -sha1 -extensions v3_ca -signkey \ private/cakey.pem -in private/ca.csr -out certs/ca.cer
152740_yYK9_1434710.png
该命令的含义如下:
x509——生成 x509 格式证书
-req——输入 csr 文件
-days——证书的有效期(天)
-sha1——证书摘要采用 sha1 算法
-extensions——按照 openssl.cnf 文件中配置的 v3_ca 项添加扩展
-signkey——签发证书的私钥
-in——要输入的 csr 文件
-out——输出的 cer 证书文件
之后看一下 certs 文件夹里生成的 ca.cer 证书文件:
152922_iD3K_1434710.png

用根证书签发 server 端证书

和生成根证书的步骤类似,这里就不再介绍相同的参数了。

a). 生成服务端私钥

openssl genrsa -aes256 -out private/server-key.pem 1024

b). 生成证书请求文件

openssl req -new -key private/server-key.pem -out private/server.csr -subj \ "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname"

c). 使用根证书签发服务端证书

openssl x509 -req -days 365 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/cakey.pem \ -CAserial ca.srl -CAcreateserial -in private/server.csr -out certs/server.cer
这里有必要解释一下这几个参数:
-CA——指定 CA 证书的路径
-CAkey——指定 CA 证书的私钥路径
-CAserial——指定证书序列号文件的路径
-CAcreateserial——表示创建证书序列号文件 (即上方提到的 serial 文件),创建的序列号文件默认名称为 - CA,指定的证书名称后加上. srl 后缀
注意:这里指定的 - extensions 的值为 v3_req,在 OpenSSL 的配置中,v3_req 配置的 basicConstraints 的值为 CA:FALSE,如图:
145405_I71X_1434710.png
而前面生成根证书时,使用的 - extensions 值为 v3_ca,v3_ca 中指定的 basicConstraints 的值为 CA:TRUE,表示该证书是颁发给 CA 机构的证书,如图:
145718_5CsH_1434710.png
在 x509 指令中,有多重方式可以指定一个将要生成证书的序列号,可以使用 set_serial 选项来直接指定证书的序列号,也可以使用 - CAserial 选项来指定一个包含序列号的文件。所谓的序列号是一个包含一个十六进制正整数的文件,在默认情况下,该文件的名称为输入的证书名称加上. srl 后缀,比如输入的证书文件为 ca.cer,那么指令会试图从 ca.srl 文件中获取序列号,可以自己创建一个 ca.srl 文件,也可以通过 - CAcreateserial 选项来生成一个序列号文件。

用根证书签发 client 端证书

和签发 server 端的证书的过程类似,只是稍微改下参数而已。

a). 生成客户端私钥

openssl genrsa -aes256 -out private/client-key.pem 1024

b). 生成证书请求文件

openssl req -new -key private/client-key.pem -out private/client.csr -subj \ "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname"

c). 使用根证书签发客户端证书

openssl x509 -req -days 365 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/cakey.pem \ -CAserial ca.srl -in private/client.csr -out certs/client.cer
需要注意的是,上方签发服务端证书时已经使用 - CAcreateserial 生成过 ca.srl 文件,因此这里不需要带上这个参数了。

至此,我们已经使用 OpenSSL 自签发了一个 CA 证书 ca.cer,并用这个 CA 证书签发了 server.cer 和 client.cer 两个子证书了:
153323_S39o_1434710.png

导出证书

a). 导出客户端证书

openssl pkcs12 -export -clcerts -name myclient -inkey
private/client-key.pem -in certs/client.cer -out certs/client.keystore
参数含义如下:
pkcs12——用来处理 pkcs#12 格式的证书
-export——执行的是导出操作
-clcerts——导出的是客户端证书,-cacerts 则表示导出的是 ca 证书
-name——导出的证书别名
-inkey——证书的私钥路径
-in——要导出的证书的路径
-out——输出的密钥库文件的路径

b). 导出服务端证书

openssl pkcs12 -export -clcerts -name myserver -inkey
private/server-key.pem -in certs/server.cer -out certs/server.keystore

c). 信任证书的导出

keytool -importcert -trustcacerts -alias www.mydomain.com
-file certs/ca.cer -keystore certs/ca-trust.keystore

#####################################################################
Netkiller Cryptography 手札 信息安全与加密
7.6. Outlook smime x509 证书
7.6.1. 快速创建自签名证书

以下适合个人使用

openssl genrsa -out ca.pem 1024
openssl req -new -out neo.csr -key ca.pem
openssl x509 -req -in neo.csr -out neo.cer -signkey ca.pem -days 365
openssl pkcs12 -export -clcerts -in neo.cer -inkey ca.pem -out neo.p12

安装 cer 与 p12 两个证书,然后打开 outlook 测试

Example 7.3. 快速创建自签名证书

[root@localhost smime]# openssl genrsa -out ca/ca.pem 1024
Generating RSA private key, 1024 bit long modulus
...............++++++
...................++++++
e is 65537 (0x10001)

[root@localhost smime]# openssl req -new -out ca/ca.csr -key ca/ca.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,

If you enter '.', the field will be left blank.

Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:GD
Locality Name (eg, city) [Default City]:SZ
Organization Name (eg, company) [Default Company Ltd]:XXX Ltd
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:neo
Email Address []:neo.chan@live.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[root@localhost smime]# openssl x509 -req -in ca/ca.csr -out ca/ca-cert.cer -signkey ca/ca.pem -days 365
Signature ok
subject=/C=CN/ST=GD/L=SZ/O=XXX Ltd/CN=neo/emailAddress=neo.chan@live.com
Getting Private key

[root@localhost smime]# openssl pkcs12 -export -clcerts -in ca/ca-cert.cer -inkey ca/ca.pem -out ca/ca.p12
Enter Export Password:
Verifying - Enter Export Password:

更便捷的方法

openssl genrsa -out ca.pem 1024
openssl req -new -out neo.csr -key ca.pem -subj "/C=CN/ST=GD/L=SZ/O=Internet Widgits Pty Ltd/OU=IT/CN=neo/emailAddress=neo@668x.net"
openssl x509 -req -in neo.csr -out neo.cer -signkey ca.pem -days 365
openssl pkcs12 -export -in neo.cer -inkey ca.pem -out neo.p12 -name "neo"

7.6.2. 企业或集团方案
7.6.2.1. 证书环境

% mkdir keys
% cd keys/

建立空文件 index.txt 用来保存以后的证书信息,这是 OpenSSL 的证书数据库:

touch index.txt

建立一个文件 serial 在文件中输入一个数字,做为以后颁发证书的序列号,颁发证书序列号就从你输入的数字开始递增:

echo 01 > serial

7.6.2.2. 颁发 CA 证书

首先创建 CA 根证书私钥文件,使用 RSA 格式,1024 位:

% openssl genrsa -des3 -out ca.key 1024

Example 7.4. 创建 CA 根证书

% openssl genrsa -des3 -out ca.key 1024
Generating RSA private key, 1024 bit long modulus
...........................++++++
...........................................++++++
e is 65537 (0x10001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:

私钥在建立时需要输入一个密码用来保护私钥文件,私钥文件使用 3DES 加密; 也可以不进行加密,这样不安全,因为一旦 ca 证书遗失,别人就可以随意颁发用户证书:

openssl genrsa -out ca.key 1024

利用建立 RSA 私钥,为 CA 自己建立一个自签名的证书文件:

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

生成证书的过程中需要输入证书的信息,

Example 7.5. 创建自签名的证书

% openssl req -new -x509 -days 365 -key ca.key -out ca.crt
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,

If you enter '.', the field will be left blank.

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GD
Locality Name (eg, city) []:Shenzhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Your Company Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:Neo Chan
Email Address []:neo.chan@live.com

7.6.2.3. 颁发客户证书

生成客户证书的私钥文件,与生成 CA 根证书文件的方法一样,

openssl genrsa -des3 -out client.key 1024

OpenSSL 生成客户端证书的时候,不能直接生成证书,而是必须通过证书请求文件来生成,因此现在我们来建立客户端的证书请求文件,生成的过程中一样要输入客户端的信息:

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

有了证书请求文件之后,就可以使用 CA 的根证书、根私钥来对请求文件进行签名,生成客户端证书 client.pem 了:

openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA ca.crt -CAkey ca.key -days 365 -CAserial serial

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

[Note] Note
到这里为止,根 CA 为客户端签发证书的过程就结束了。
7.6.2.4. 吊销已签发的证书

使用 ca 中的 -revoke 命令:

openssl ca -revoke client.pem -keyfile ca.key -cert ca.crt

证书被吊销之后,还需要发布新的 CRL 文件:

openssl ca -gencrl -out ca.crl -keyfile ca.key -cert ca.crt

7.7. 证书转换

PKCS 全称是 Public-Key Cryptography Standards ,是由 RSA 实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准,PKCS 目前共发布过 15 个标准。 常用的有:
PKCS#7 Cryptographic Message Syntax Standard
PKCS#10 Certification Request Standard
PKCS#12 Personal Information Exchange Syntax Standard
X.509 是常见通用的证书格式。所有的证书都符合为 Public Key Infrastructure (PKI) 制定的 ITU-T X509 国际标准。
PKCS#7 常用的后缀是: .P7B .P7C .SPC
PKCS#12 常用的后缀有: .P12 .PFX
X.509 DER 编码 (ASCII) 的后缀是: .DER .CER .CRT
X.509 PAM 编码 (Base64) 的后缀是: .PEM .CER .CRT
.cer/.crt 是用于存放证书,它是 2 进制形式存放的,不含私钥。
.pem 跟 crt/cer 的区别是它以 Ascii 来表示。
pfx/p12 用于存放个人证书 / 私钥,他通常包含保护密码,2 进制方式
p10 是证书请求
p7r 是 CA 对证书请求的回复,只用于导入
p7b 以树状展示证书链 (certificate chain),同时也支持单个证书,不含私钥。
7.7.1. CA 证书

用 openssl 创建 CA 证书的 RSA 密钥 (PEM 格式):

openssl genrsa -des3 -out ca.key 1024

7.7.2. 创建 CA 证书有效期为一年

用 openssl 创建 CA 证书 (PEM 格式, 假如有效期为一年):

openssl req -new -x509 -days 365 -key ca.key -out ca.crt -config openssl.cnf

openssl 是可以生成 DER 格式的 CA 证书的,最好用 IE 将 PEM 格式的 CA 证书转换成 DER 格式的 CA 证书。
7.7.3. x509 转换为 pfx

openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt

7.7.4. PEM 格式的 ca.key 转换为 Microsoft 可以识别的 pvk 格式

pvk -in ca.key -out ca.pvk -nocrypt -topvk

7.7.5. PKCS#12 到 PEM 的转换

openssl pkcs12 -nocerts -nodes -in cert.p12 -out private.pem
验证
openssl pkcs12 -clcerts -nokeys -in cert.p12 -out cert.pem

7.7.6. 从 PFX 格式文件中提取私钥格式文件 (.key)

openssl pkcs12 -in mycert.pfx -nocerts -nodes -out mycert.key

7.7.7. 转换 pem 到到 spc

openssl crl2pkcs7 -nocrl -certfile venus.pem -outform DER -out venus.spc

用 -outform -inform 指定 DER 还是 PAM 格式。例如:

openssl x509 -in Cert.pem -inform PEM -out cert.der -outform DER

7.7.8. PEM 到 PKCS#12 的转换

openssl pkcs12 -export -in Cert.pem -out Cert.p12 -inkey key.pem

IIS 证书

cd c:\openssl
set OPENSSL_CONF=openssl.cnf
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt

server.key 和 server.crt 文件是 Apache 的证书文件,生成的 server.pfx 用于导入 IIS
7.7.9. How to Convert PFX Certificate to PEM Format for SOAP

$ openssl pkcs12 -in test.pfx -out client.pem
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

7.7.10. DER 文件(.crt .cer .der)转为 PEM 格式文件

转换 DER 文件 (一般后缀名是. crt .cer .der 的文件) 到 PEM 文件
openssl x509 -inform der -in certificate.cer -out certificate.pem
转换 PEM 文件到 DER 文件
openssl x509 -outform der -in certificate.pem -out certificate.der

Openssl 格式转换

Certificate 和 key 可以存成多种格式, 常见的有 DER , PEM , PFX

DER

將 certificate 或 key 用 DER ASN.1 编码的原始格式, certificate 就是依照 X.509 的方式编码, key 則是又能分為 PKCS#1 和 PKCS#8

PEM

把 DER 格式的 certificate 或 key 使用 base64-encoded 编码后在头尾上资料标明档案类型

Certificate

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

RSA private key (PKCS#1)

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

RSA public key (PKCS#1)

-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

RSA private key (PKCS#8, key 沒加密 )

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

RSA public key (PKCS#8)

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

RSA private key (PKCS#8, key 有加密 )

-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

PKCS#7

这个格式用来传递签署或加密的资料, 档案里可以包含整个用到的 certificate chain

PKCS#12 (PFX)

这个格式可以把 private key 和整个 certificate chain 存程一个档案

格式转换

openssl 预设输入输出的格式都是 PEM, 要转换格式很简单, 搭配 inform, outform 参数就可以了

Certificate PEM 转 DER

openssl x509 -in cert.pem -outform der -out cert.der

Certificate DER 转 PEM

openssl x509 -inform der -in cert.der -outform der -out cert.pem

RSA key 的转换比较多一些, 有 private/public key, PKCS#1/PKCS#8, DER/PEM, 以下只都是用 PEM 格式, 要转成 DER 只要加入 inform, outform 参数就可以了

输出 public key 指令

从 certificate 输出

openssl x509 -in cert.pem -pubkey -noout > public.pem

从 private key 输出

openssl rsa -in private.pem -pubout -out public.pem

PKCS#1/PKCS#8 转换
openssl 有多个指令会产生 private key,genpkey 会产生 PKCS#8 格式 genrsa 会产生 PKCS#1 格式,
上面兩个输出 public key 的指令都是 PKCS#8 格式

Public key 格式转换, 主要是搭配 RSAPublicKey_in,RSAPublicKey_out, 這兩个参数, rsa command 的 help 沒有显示这两个参数, 说明文件才有

Public key: PKCS#8 -> PKCS#1

openssl rsa -pubin -in public.pem -RSAPublicKey_out -out public_pkcs1.pem

Public key: PKCS#1 -> PKCS#8

openssl rsa -RSAPublicKey_in -in public_pkcs1.pem -out public_pkcs8.pem

也可以在从 private key 输出時直接设定输出格式

openssl rsa -in private.pem -RSAPublicKey_out -out public_pkcs1.pem

Private key 格式转换, 主要是用 pkcs8 指令, 搭配 topk8 参数作转换, 若不加密就再加上 nocrypt

Private key: PKCS#1 -> PKCS#8

openssl pkcs8 -in private_pkcs1.pem -topk8 -nocrypt -out private_pkcs8.pem

Private key: PKCS#8 -> PKCS#1

openssl pkcs8 -in private_pkcs8.pem -nocrypt -out private_pkcs1.pem

用 OpenSSL 0.9.8 可以, 之后的版本用 pkcs8 这个指令输出都是 PKCS#8, 這指令只是用於 0.9.8

用 0.9.8 之后的版本直接用 rsa 转换即可

openssl rsa -in private_pkcs8.pem -out private_pkcs1.pem

从 PKCS#7 输出 certificate
目前最常遇到的是 DOCSIS secure upgrade 用的 Code File, 前面會有一段 DER 编码的资料, 包含 1~2 张 CVC

openssl pkcs7 -in code.p7b -print_certs -out certs.pem

从 PKCS#12(PFS) 输出 certificate 和 private key

openssl pkcs12 -in key_cert.pfx -nodes -out key_cert.pem

打完指令会要求输入 pfx file 的密码, 若上述指令没加入 nodes, 会再要求输入输出的 private key 要用的密碼

把 private key 和 certificate 以及 CA 打包成 PKCS#12
者功能我是用来制作 FreeRADIUS client 端, 给 windows 用的懒人包, 输入的 private key (client.key), certificate (client.crt), certificate-chain(cert-chain.crt) 都是用 PEM 格式

openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt -certfile cert-chain.crt

打完指令会要求输入 pfx file 的密码, 之後在 windows 下直接开启 client.p12 敲完密码, 下一步到底, 凭证就会放到对的地方了

`