openssl相关知识

写在前面

做到密码学的题给秘钥经常用pem格式的,这里就需要学习一下openssl怎么处理秘钥,加密文件等知识

ANS.1 & DER & PEM

openssl的数据编码规则是基于ans.1:
ASN.1(=Abstract Syntax Notation One),是一种结构化的描述语言,包括两部分,数据描述语言和数据编码规则。标准ASN.1编码规则有规范编码规则(CER,Canonical Encoding Rules)、唯一编码规则(DER,Distinguished Encoding Rules)、压缩编码规则(PER,Packed Encoding Rules)和XML编码规则(XER,XML Encoding Rules)。

openssl使用pem作为基本的文件编码格式,pem和der的关系如下图所示,其中几种加密环节是可选的:

pem和der
从本质上来说,openssl是pem编码就是在der编码的技术上进行Base64编码,然后添加一些头尾信息组成,可以通过openssl指令对der和pem进行格式转换。

Distinguished Encoding Rules (DER) is a binary serialization of ASN.1 format. It is often used for cryptographic data such as certificates, but has other uses.

即DER是二进制格式的秘钥,PEM是把DER给base64编码这样看起来有好一点

密钥编码

openssl有多种形式的密钥,openssl提供PEM和DER两种编码方式对这些密钥进行编码,并提供相关指令可以使用户在这两种格式之间进行转换。一个经过加密的PEM编码密钥文件会在PEM文件中增加一些头信息,表明密钥的加密状态,加密算法及初始化向量等信息。

公钥PEM

PKCS #1

KCS #1 标准是专门为 RSA 密钥进行定义的,其对应的 PEM 文件格式如下:

1
2
3
-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----

上面的内容 BASE64 ENCODED DATA 指的就是 ANS.1 的 DER 的 Base64 编码。其ASN.1的格式为:

1
2
3
4
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}

  • modulus 是RSA的模数n
  • publicExponent 是RSA公钥e

PKCS #8

PKCS#8 标准定义了一个密钥格式的通用方案,它不仅仅为 RSA 所使用,同样也可以被其它密钥所使用。其对应的PEM文件格式如下:

1
2
3
-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

注意,这里就没有 RSA 字样了,因为 PKCS#8 是一个通用型的秘钥格式方案;其中的 BASE64 ENCODED DATA 所标注的内容为 PEM 格式中对 DER 原始二进制进行的 BASE64 编码:

1
2
3
4
5
6
7
8
PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
PublicKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}

PKCS#8 虽然名字叫做 Private-Key Information Syntax Specification,但是实际上,可以看到,它同样可以用作 Public Key 的格式定义;而 PKCS#8 是站在 PKCS#7 CMS 的基础之上进行编码格式定义的。

私钥PEM

PKCS #1

PKCS#1 是专门为 RSA 所涉及的,其对应的 PEM 格式如下:

1
2
3
-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

原始的 DER 格式结构,既是 ASN.1 的数据结构:

1
2
3
4
5
6
7
8
9
10
11
12
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}

  • version 是版本号,两个素数为0,如果使用了多素数,则版本号应该是1。
    Version ::= INTEGER { two-prime(0), multi(1) }
    (CONSTRAINED BY {– version must be multi if otherPrimeInfos present –})
  • modulus 是RSA模数n。
  • publicExponent 是RSA的公钥e。
  • privateExponent 是RSA的私钥d。
  • prime1 是n的素数因子p
  • prime2 是n的素数因子q
  • exponent1 等于d mod (p − 1)。
  • exponent2 等于d mod (q − 1)。
  • coefficient 等于 q–1 mod p。
  • otherPrimeInfos 按顺序包含了其它素数r3, 如果version是0 ,它应该被忽略;而如果version是1,它应该至少包含OtherPrimeInfo的一个实例。

PKCS #8

未加密PEM格式:

1
2
3
-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

对应的DER:

1
2
3
4
5
6
7
8
9
PrivateKeyInfo ::= SEQUENCE {
version Version,
algorithm AlgorithmIdentifier,
PrivateKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}

针对私钥的内容进行加密PEM格式:

1
2
3
-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64 ENCODED DATA
-----END ENCRYPTED PRIVATE KEY-----

DER格式:

1
2
3
4
5
6
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm EncryptionAlgorithmIdentifier,
encryptedData EncryptedData
}
EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
EncryptedData ::= OCTET STRING

生成私钥

openssl有多种方法生成私钥:

  • genrsa生成RSA密钥。
  • req在生成req证书请求时同时产生密钥。
  • genpkey除了可以生成RSA密钥外,还可以生成DSA、DH密钥。

举例说明:

1
openssl genpkey -algorithm RSA -out privatekey.pem -pass pass:1234 -des-ede3-cbc

查看秘钥

  • 查看私钥openssl rsa -in rsa.key
  • 查看公钥openssl rsa -in rsa.key -pubout
  • 查看公钥和modulus openssl rsa -in rsa.key -modulus
  • 查看密钥的详细信息,包含component prime等细节信息,这些信息的值都是冒号分割的,称为abstractopenssl rsa -in rsa.key -text
  • 查看只有public key的文件openssl rsa -in pub.txt -pubin
  • 注:pub.txt 可由openssl rsa -in rsa.key -pubout >pub.txtopenssl rsa -in rsa.key -pubout -out pub.txt产生如果pub.txt 中不是公钥将报错, -pubin 仅仅说明 -in 所指定的文件里面是什么
  • 只查看key的其他信息,不显示keyopenssl rsa -in rsa.key -noout

使用rsautl

DESCRIPTION

The rsautl command can be used to sign, verify, encrypt, and decrypt data using the RSA algorithm.

1
openssl rsautl [-in file] [-out file] [-inkey file] [-pubin] [-certin] [-sign] [-verify] [-encrypt] [-decrypt] [-pkcs] [-ssl] [-raw] [-hexdump] [-asn1parse]

Options

-in filename

specifies the input file name to read data from or standard input if this option is not specified.

-out filename

specifies the output file name to write to or standard output by default.

-inkey file

specifies the input key file, by default it should be an RSA private key.

-pubin

specifies the input file is an RSA public key.

-certin

indicates that the input is a certificate containing an RSA public key.

-sign

signs the input data and output the signed result. This requires and RSA private key.

-verify

verifies the input data and output the recovered data.

-encrypt

**encrypts the input data using an RSA public key.

-decrypt

**decrypts the input data using an RSA private key.

-pkcs
-oaep
-ssl
-raw

specifies the padding to use: PKCS#1 v1.5 (the default), PKCS#1 OAEP, special padding used in SSL v2 backwards compatible handshakes, or no padding, respectively. For signatures, only -pkcs and -raw can be used.

-hexdump

hex dumps the output data.

-asn1parse

asn1parse the output data, this is useful when combined with the -verify option.

example

签名

1
openssl rsautl -sign -in file -inkey key.pem -out sig

验证签名

1
openssl rsautl -verify -in sig -inkey key.pem

加密

1
openssl rsautl -encrypt -in hello -inkey test_pub.key -pubin -out hello.en

解密

1
openssl rsautl -decrypt -in hello.en -inkey test.key -out hello.de

文章目录
  1. 1. 写在前面
  2. 2. ANS.1 & DER & PEM
  3. 3. 密钥编码
  4. 4. 公钥PEM
    1. 4.1. PKCS #1
    2. 4.2. PKCS #8
  5. 5. 私钥PEM
    1. 5.1. PKCS #1
    2. 5.2. PKCS #8
  6. 6. 生成私钥
  7. 7. 查看秘钥
  8. 8. 使用rsautl
    1. 8.1. DESCRIPTION
    2. 8.2. Options
    3. 8.3. example
|