数字签名由表入里

Posted by Jason on Sunday, December 16, 2018

TOC

使用OpenSSL生成RSA公私钥

项目中需要用到公私钥实现数字签名、验签,通过下面的命令生成的:

1.openssl genrsa -out rsa_private_key_2048.pem 2048 #生成rsa私钥,X509编码,2048位
2.openssl pkcs8 -in rsa_private_key_2048.pem -out rsa_private_key_2048_pkcs8.pem -nocrypt -topk8 #转换为PKCS#8编码
3.openssl rsa -in rsa_private_key_2048.pem -out rsa_public_key_2048.pem -pubout #导出对应的公钥,X509编码
  • 生成2048位的rsa私钥,默认是X509编码,这一步生成的私钥文件只供第2、3步使用,并没有实际用处;
  • 使用第1步生成的私钥文件生成PKCS#8编码的私钥文件,这一步生成的文件为最终使用的私钥文件;
  • 使用第1步生成的私钥文件生成对应的公钥文件,这一步生成的公钥文件为最终使用的公钥文件;

之前对数字签名证书概念不是很了解,特此记录下学习笔记。

openssl 工具

OpenSSL 是一个开源项目,其组成主要包括一下三个组件:

  • openssl:多用途的命令行工具

  • libcrypto:加密算法库

  • libssl:加密模块应用库,实现了ssl及tls

openssl可以实现:秘钥证书管理、对称加密和非对称加密更多简介和官网。

基本概念

  • crt(证书): 表明身份的一种文件,包含机构的公钥和域名等信息。典型的在浏览器中请求 https 网站时,浏览器建立 http 连接前会做 tls 认证,需要确保数据来源是合法真实的网站。而在建立连接过程中由 server 端传送给浏览器来表明身份文件就是证书。

  • csr: 证书签名请求文件(Certificate Signning Request),是一种证书签发请求文件,由请求方生成,文件内容包含请求方的公钥和机构信息等。

  • 公/私钥:rsa 算法是一种非对称加密算法,公/私钥加密的明文可以通过私/公钥解密。但是,通过私钥可以反推出公钥,所以通常情况下s端使用私钥加解密、c端使用公钥加密。

子命令

  • genrsa: 可以用来生成私钥,能够指定加密算法和私钥长度;
  • rsa: 通常用来生成公钥;
  • req: 通常用于生成自签名证书、或者csr;
  • x509: 可以用于显示证书的内容,转换其格式,给CSR签名等X.509证书的管理工作;
  • ca: 通常用于证书签发;

数字签名

证书签发流程

  1. 申请人生成公钥、私钥、csr 文件:
#生成私钥 2048位密钥,保存到mykey.pem
openssl genrsa -out mykey.pem 2048

#生成csr  sha256 签名
openssl req -new -key mykey.pem -sha256  -out server.csr

# 查看信息
openssl req -in my.csr -noout -text

# 也可以通过一步命令生成
# openssl req -nodes -newkey rsa:2048 -sha256 -keyout mykey.pem -out server.csr

#生成公钥
openssl rsa -in mykey.pem -pubout
  1. 交给 CA 签发证书:
# 生成CA 私钥
openssl genrsa -out ca.key 2048

#生成CA自签名证书:
openssl req -new -x509 -key ca.key -out ca.crt 

#查看证书信息
openssl x509 -in ca.crt -noout -xxx

#签发证书
openssl x509 -req -CAcreateserial -CA ca.crt -CAkey ca.key -in server.csr -out server.crt

#查看信息
openssl x509 -in server.crt -noout -text

问题记录

明文长度限制问题

在对长文本明文进行加密处理的时候, 如果文本长度超过 117 字节需要对文本做分块处理。

RSA算法本身要求加密内容也就是明文长度m必须 0<m< 密钥长度n。如果小于这个长度就需要进行 padding,因为如果没有 padding,就无法确定解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,但对二进制数据就很难,因为不确定后面的0是内容还是内容结束符。而只要用到 padding,那么就要占用实际的明文长度,于是实际明文长度需要减去padding字节长度。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。

这样,对于1024长度的密钥。128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。

参考

  1. openssl的介绍和使用
  2. OpenSSL生成根证书CA及签发子证书

「真诚赞赏,手留余香」

Jason Blog

真诚赞赏,手留余香

使用微信扫描二维码完成支付


comments powered by Disqus