密码学

Openssl

什么是Openssl

OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

基本功能

openssl是一个开源程序的套件、这个套件有三个部分组成:

  • libcryto,这是一个具有通用功能的加密库,里面实现了众多的加密库;
  • libssl,这个是实现ssl机制的,它是用于实现TLS/SSL的功能;
  • openssl,是个多功能命令行工具,它可以实现加密解密,甚至还可以当CA来用,可以让你创建证书、吊销证书。

密钥算法类型及密钥编码

密钥算法类型

目前主要包含两种密钥算法类型:

  • 对称机密算法:加密和解密时使用相同的密钥
    对称加密
  • 非对称加密算法:加密密钥与解密密钥成对出现,一般为私钥和公钥。私钥用于签名或加密;公钥用于验签或解密。
    非对称加密
    对称机密算法目前主要包括:AES,DES,3DES;非对称加密算法主要包括RSA,ECC。

密钥编码及后缀

编码格式

  • PEM:Privacy Enhanced Mail,打开看文本格式,以"-----BEGIN…"开头, "-----END…"结尾,内容是BASE64编码.
  • DER:Distinguished Encoding Rules,辨别编码规则 (DER) 可包含所有私钥、公钥和证书。它是大多数浏览器的缺省格式,并按 ASN1 DER 格式存储。它是无报头的,PEM 是用文本报头包围的 DER。

PEM 转 DER: openssl x509 -in cert.crt -outform der -out cert.der
DER 转 PEM: openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
注:其中x509是密码学里公钥证书的格式标准,要转key,将x509改为rsa等。

文件后缀名

  • CRT:certificate,常见于*NIX系统,有可能是PEM编码,也有可能是DER编码,大多数应该是PEM编码;
  • CER:certificate,还是证书,常见于Windows系统,同样的,可能是PEM编码,也可能是DER编码,大多数应该是DER编码;
  • KEY:通常用来存放一个公钥或者私钥,并非X.509证书,编码同样的,可能是PEM,也可能是DER;
  • CSR:Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥;
  • PFX/P12:predecessor of PKCS#12, 包含了私钥与公钥证书,私钥采用密码保护,对ngnix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中。
  • JKS:Java Key Storage,这是Java的专利,跟OpenSSL关系不大,利用Java的一个叫"keytool"的工具,可以将PFX转为JKS,当然了,keytool也能直接生成JKS,不过在此就不多表了.

PKCS

PKCS类型,即公钥密码学标准,可参考:维基百科-公钥密码学标准

类型名称简介
PKCS#1RSA密码编译标准(RSA Cryptography Standard)定义了RSA的数理基础、公/私钥格式,以及加/解密、签/验章的流程
PKCS#8私钥消息表示标准(Private-Key Information Syntax Standard)Apache读取证书私钥的标准
PKCS#10证书申请标准(Certification Request Standard)参见RFC 2986。规范了向证书中心申请证书之CSR(certificate signing request)的格式
PKCS#12个人消息交换标准(Personal Information Exchange Syntax Standard)定义了包含私钥与公钥证书(public key certificate)的文件格式。私钥采密码(password)保护。常见的PFX就履行了PKCS#12

对称加密算法

对于对称加密算法,主要集中在对openssl的使用上,可以先看一下帮助文档:

$ openssl enc -h
unknown option '-h'
options are
-in <file>     input file
-out <file>    output file
-pass <arg>    pass phrase source
-e             encrypt
-d             decrypt
-a/-base64     base64 encode/decode, depending on encryption flag
-k             passphrase is the next argument
-kfile         passphrase is the first line of the file argument
-md            the next argument is the md to use to create a key
                 from a passphrase. See openssl dgst -h for list.
-S             salt in hex is the next argument
-K/-iv         key/iv in hex is the next argument
-[pP]          print the iv/key (then exit if -P)
-bufsize <n>   buffer size
-nopad         disable standard block padding
-engine e      use engine e, possibly a hardware device.
Cipher Types
-aes-128-cbc               -aes-128-cbc-hmac-sha1     -aes-128-cbc-hmac-sha256
-aes-128-ccm               -aes-128-cfb               -aes-128-cfb1
-aes-128-cfb8              -aes-128-ctr               -aes-128-ecb
-aes-128-gcm               -aes-128-ofb               -aes-128-xts
-aes-192-cbc               -aes-192-ccm               -aes-192-cfb

通过输入密码,进行加密

# password from stdin
$ openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass

# password from cmd line
$ openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass pass:123456

# password from file
$ openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass file:passwd.txt

# password from enviroment
$ openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass env:passwd

# password from fd
$ openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass fd:1  
  • 对称加密的使用中,虽然我们输入了-pass,指定了密码,但是本质是采用key和iv向量进行加密的,我们输入的-pass,会转换成key和iv
  • 为了增强安全性,在把用户密码转换成 key / iv 的时候需要使用盐值,默认盐值随机生成。使用-S参数,则盐值由用户指定。也可指用-nosalt指定不使用盐值,但降低了安全性,不推荐使用。
  • 因为本质是采用 key / iv 加密,所以我们可以直接用 key / iv 解密或者加密

手动指定Key和IV值,指定key / iv 后,-pass参数不起作用

$ openssl enc -aes-128-cbc -in plain.txt -out encrypt.txt  -K 1223 -iv f123 -p

非对称加密算法

RSA

算法原理

暂不详解,参考:RSA算法探秘

密钥生成

  • OpenSSL明文生成命令如下:
## generate private key without password
$ openssl genrsa -out rsa.key 2048

## export public key
$ openssl rsa -in rsa.key -pubout -out rsa.pub
  • 明文私钥内容如下:BEGIN RSA PRIVATE KEY为PKCS#1格式
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEArzMYu9B07EwgLma0c+BK+vGAGrVqvRnhxPr4o7NVAfCqKe6V
7evym0ClkCK4NJ7s8bHJjmTxBXIpZuPOJBJhG2H0EALFap7sfzSxbbHIUkoJDO/c
kuo7enZ/R5UIs/esuua5/oiPlx3XY/9+OHviuyCtCPy0dFi7j9TNxstsUj7eXs+Y
r1TC+bA7CointNqi9TDwU3cM74jdgUrIU/uLtqL2mB22RCa80FfcURp7tQYVDyPO
nHex4ijjjyl1zi26YI1kxZf8dRlRoFfGTayrS/8Txp0KqGKEsLJyYQ8DeuEhW9gW
/Ka340ZC7ObVMqTzMJ7pzxyWmbRqHOIlO54jxQIDAQABAoIBAB2gHEyWAU97x+1Q
vK7jfIpWj/z0NGppl/3BGo5D4toDIiMZDw0+WrXaBqUK2e87+IEeOSD0/LSZC1s0
pkT/PqBsveJ/NXbEDOWtuVr9NwyDLGidnsTRCuG4a+lk0CXueazZGxZpbS52g1eL
eoJ+oGZYLipY4QLThlPZ/jnhaB238CfAQ+KfkkxdJcPEJWzONalWsTrb0RK+0WHZ
sgwJwCn9zBECZYNkHKKV0G1/TOyslZTZwo8aXCsEtwQmtwqtuYEaPCTrJ8YPpjoD
HjEdt6sUcCJd98aHxJ9zuABgDlq7NZAsAhgmdPPcnXu5xSFgFw7yPj/6UDgZxtcb
5VkSMsECgYEA2a9nKL241eMnqJ9/dBE84fNFEg0C9hNEljGr8sxilg0cs3nk4v6P
GRVcl6fjmRm6bIUzHPmFFFBOzr9JIlKv71II1S1Dn4l0gIuT5epPB1OlinBCU+Ur
jjhuZ3UOeZQ3LF9nKeDqn6jDjY6jXCQRK9xqKmzZ2yCUGrwYKpa0JskCgYEAzgla
B+y5bWPLYC0sv76yz5I+yTfIl7PAO6clgzSgBhHNFkjPA0eWcA/AA9tZS5Nz5MB5
ACiKN82dmnOedkkpJg29CTc7KttNTie5A7n+reKKV8qMMSM7I/MbQn/j7GIrW/uG
6WiZveXtK7o4jLZOGPE2nTx0iFGrrUjLK3TURx0CgYAdD3J5GOLNAvcvZqOQLiDv
lRdacow7p5TXbCglUK20lGmJeDNbLlqSIazrvgj/TlT52cpaCuF+Nb5fkV/FCj7c
dxogw1ssuB/qbTfAUMheFQebdKMWKhjncpcijpjxGB1Jei7+gz0vNUtt4WXjjhkQ
vusZYNCwlSfQbd3YCahhKQKBgC/xeSOy8AsGV8LPgEQ2CcHHVBjahDDYwPigklgP
nNUMu15eHt2ygM0evR2oowS1ERi/uOhShqcpj2zrTopTx+F0/PHyCjCUy05Oa/z0
ANFRj8OR/EFK424gGc3FmLHevhwvUVtq3auUnzW3pYUIvu+K4ZyA/tThvEMcVzqL
ewH5AoGBAKx3QRwdnCYFZTV26DO1LqjT3b2AbGBtM18u2mPwf593qJt3oJdJMGii
LGkGNZgCm88gMN/sY+chSJumlCHToFHLiovVIManpkv0Y7sXHw6TUeSjg5hB84b6
If/YzYcoFIpi1uKGVMSTnEdzLx1sjqM00qsVZz9cz8f71TMOOsQx
-----END RSA PRIVATE KEY-----
  • 公钥内容如下:BEGIN PUBLIC KEY为PKCS#8格式
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArzMYu9B07EwgLma0c+BK
+vGAGrVqvRnhxPr4o7NVAfCqKe6V7evym0ClkCK4NJ7s8bHJjmTxBXIpZuPOJBJh
G2H0EALFap7sfzSxbbHIUkoJDO/ckuo7enZ/R5UIs/esuua5/oiPlx3XY/9+OHvi
uyCtCPy0dFi7j9TNxstsUj7eXs+Yr1TC+bA7CointNqi9TDwU3cM74jdgUrIU/uL
tqL2mB22RCa80FfcURp7tQYVDyPOnHex4ijjjyl1zi26YI1kxZf8dRlRoFfGTayr
S/8Txp0KqGKEsLJyYQ8DeuEhW9gW/Ka340ZC7ObVMqTzMJ7pzxyWmbRqHOIlO54j
xQIDAQAB
-----END PUBLIC KEY-----
  • OpenSSL密文生成命令如下:
## generate rsa private key with password
$ openssl genrsa -aes256 -out name_private.key 2048
  • 密文如下:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,6BD39B13ECA6BE46F418ECC341EEC626

p4TtCgJUP7Ik/f2xqJrJ3zfbGiA49T3Vrf9naKSYrZawGVhqYxRu+fiXePxKc25L
8rdnwCiF7x2xtR9uNWcWlFIe76KlPqrFMqBzVrEloOb0bM9TvZ06ZsYE6DrlH2xj
1NLzKz9I3CQ9M/VZIHInzvm7J1vFPFwSH5NSjq3oIVnMgfPMzaq5DCBYIxJ4nOEm
fGRx9bXnTzpIPCR6MrgmZiWzEt3akgkKSzQlfEEOLWfjEDBvJmuLO20CIfj+Q8Y6
rTMroud7sZb+FFDHAB3BolEp2Bqfi0YQJ8rMKTl+On3QFdBQD+v9jcTurqhD1C47
3KHieg18ZN2OxNTHHJMo0A1VEent6lvBSHIPKtgyUBP87+nUPsWoBDQV+zoL3pCP
O4zlY35WEt6BU+ImupkNNjZ70Sgfr3hUdXN3ZZi2rWUqGABzUpBREF9UuQVuqOeO
lpswWKMKQIXuvbZ70OdZ6JsUBMdeEIZSvEDeez85ef2GwuB6IvJtxmWNf4POiJxJ
oNponrYCh6RatQLDKgg0iqE2fkyq6QoKN8mFIHNwG7LS5CsSCiNzsj1lhl4pm2eB
5NQrInKa/sDFN1uFmtrWGw1bhyJdUPGPhaw5Xb1DRh1dbxooieEaCysuu+RpZpqc
AVwhrKf2IB2N82mEiQfD0FwJ4FGtBhlAmtMHHjtlDmbh1qzOYs1wUKpPY8C72fza
XwfS8kMdac3HWJc4osJ+/YoQv9cQtQX/DwiA/86nxRiogjbtDYERneu2ucxnzFrV
i0l9frX2qvkuXWArlT9+0zFZA3fTF0fP5j2mrf8tdTE+OdAVqRW50l2JiVId8qUv
2D5ygiHn1h+zPreeckA1386HMYwPirHcr/JpzrI5R+hCgXGEVi2GQISRjsVa2sqS
hNEirQFe7M6HPgtPaXcjKm/R8MY2aVHI3irTccXvIjDo2GCb85ZQFLqdQOE3N+h7
xrdcDaNZV6K6ZcudUsLiiH6gjXeiTL9VeSJQdyJ5mDJpEl9297JU7CbrRwndUgTV
qJ6Q5s9r158Bb0aLQwYFx0FEwqIiQB+tZoJ1e9+H8jNuRvDn35thMrOw+QcsMsT8
7QHL741jjcB51610afi5Zb2xhUKiWwrJLLKfp+e+4B3aFnhBm8anRcwBaYaF4OWK
4O8vialNxUelI6qJqyjb9sS/9G+YCmWjkvO/Wc7CcZ2dag0cxvyV+XZllUfFaZpN
5KbIH+zv+6pa2GyeePWekvsYQstXB43lKDYYjcO89SVGwEXGw1W7TlJI9SPZl3eR
FcN/O7CEcZfA17XDsS7u6FZgLfRlLeqSpRhRxgAuB7XpdwKVazPc6fVr48h6rH/M
Po9+wDUId7wrdAnxZgETpcIVgISpszfCYGKuYc1tZXaBDZxivHCV4oTdDp9uFwF1
QB6kZIcQ2evqDLtQt5jRNHl7792RNiwWIZd66WTV2fie2YHoF42lhj7/AdbI+nDx
Wzt0bvV5/lwsrnSZbLLTGwdxs/eoDrhhuCBeChoeXsxwm0yCu7cy8Ogqv/LXu5m8
Nm7HkkZ0eldHiFhOiRSDRCfzJwCBmZt6wPnvgsslBwYA8MCN5qI2a3nxMz5rxip/
-----END RSA PRIVATE KEY-----
  • 其他命令
## view the public key
$ openssl rsa -pubin -in name.pub -noout -text

## remove the password of the private key
$ openssl rsa -in name.key -out name_plain.key

## view private key with interactive mode
$ openssl rsa -in name.key -noout -text

## view private key with a password file
$ openssl rsa -in name.key -noout -text -passin file:path/to/password

## convert from PKCS#8 to PKCS#1
$ openssl rsa -pubin -in name.pub -RSAPublicKey_out

## convert from PKCS#1 to PKCS#8
$ openssl rsa -RSAPublicKey_in -in name.pub -pubout

## encrypt with private key, actually with public key
$ openssl rsautl -encrypt -in plain.txt -inkey -inkey name.key -out enc.txt

## decrypt with private key
$ openssl rsautl -decrypt -in enc.txt -inkey name.key -out replain.txt

## encrypt with public key
$ openssl rsautl -encrypt -in plain.txt -inkey name.key -pubin -out enc1.txt

## sign with private key
$ openssl rsautl -sign -in plain.txt -inkey name.key  -out sign1.txt

## verify with public key
$ openssl rsautl -verify -in sign1.txt -inkey name.key -pubin -out replain1.txt

密钥分析

PKCS#1

RSA私钥的PKCS#1的PEM格式如下:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA OF RSAPrivateKey
-----END RSA PRIVATE KEY-----

私钥结构如下:其中比较重要的都是与RSA算法相关的整数。

RSAPrivateKey ::= SEQUENCE { 
  version Version, //版本 
  modulus INTEGER, // RSA合数模 n 
  publicExponent INTEGER, //RSA公开幂 e 
  privateExponent INTEGER, //RSA私有幂 d 
  prime1 INTEGER, //n的素数因子p 
  prime2 INTEGER, //n的素数因子q 
  exponent1 INTEGER, //值 d mod (p-1) 
  exponent2 INTEGER, //值 d mod (q-1) 
  coefficient INTEGER, //CRT系数 (inverse of q) mod p 
  otherPrimeInfos OtherPrimeInfos OPTIONAL 
}

首先,我们可以通过以下Go代码将PEM格式的私钥转换为DER格式的字节串,并解析为可用于分析的私钥结构体:

func getPrivKey(keyFile string) (*rsa.PrivateKey, error) {
  key, err := ioutil.ReadFile(keyFile)
  if err != nil {
	  return nil, err
  }

  block, _ := pem.Decode([]byte(key))
  if block == nil {
    return nil, fmt.Errorf("failed to decode pem data")
  }

  priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
  if err != nil {
    return nil, err
  }

  fmt.Println(priKey.N.Bytes()) // 模数N
  eBytes := make([]byte, 8)
  binary.BigEndian.PutUint64(eBytes, uint64(priKey.E)) // 公有幂,一般为65537
  fmt.Println(eBytes)
  fmt.Println(priKey.D.Bytes()) // 私有幂
  fmt.Println(priKey.Primes[0].Bytes()) // n的素数因子p 
  fmt.Println(priKey.Primes[0].Bytes()) // n的素数因子q
  fmt.Println(priKey.Precomputed.Dp.Bytes()) //值 d mod (p-1) 
  fmt.Println(priKey.Precomputed.Dq.Bytes()) //值 d mod (q-1) 
  fmt.Println(priKey.Precomputed.Qinv.Bytes()) // CRT系数 (inverse of q) mod p 

  return priKey, nil
}

或者也可以通过ASN.1 JS Decoder对DER进行分析,为了方便,我们直接采用第二种方式分析,如下:
image.png
其中,模数N部分如下,其他类似:
a. 02: tag
b. 82 – 81: 代表长度用1byte表示,82代表长度用2byte表示(此字节部分tag后不存在)
c. 0101: length 2bytes表示
d. 00: 在modulus数据前添加00,原因未知,请知情道友告知。
e. 模数N

PKCS#8

RSA私钥的PKCS#8的PEM格式如下

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA OF PrivateKeyInfo
-----END PRIVATE KEY-----

私钥结构如下:

PrivateKeyInfo ::= SEQUENCE {
version Version,
algorithm AlgorithmIdentifier,
PrivateKey BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE { 
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}

PKCS#1与PKCS#8互转参考:PKCS#1 <=> PKCS#8

ECC

算法原理

暂不详解,参考:ECC椭圆曲线加密算法

曲线类型

目前主要有如下曲线,其中曲线secp256k1在区块链中使用较为广泛。

$ openssl ecparam -list_curves
  secp256k1 : SECG curve over a 256 bit prime field
  secp384r1 : NIST/SECG curve over a 384 bit prime field
  secp521r1 : NIST/SECG curve over a 521 bit prime field
  prime256v1: X9.62/SECG curve over a 256 bit prime field

密钥生成

本节仅介绍secp256k1的生成,其他曲线类似

  • OpenSSL明文生成命令如下:
# generate secp256k1 private key
$ openssl ecparam -name secp256k1 -genkey -out secp256k1-key.pem

# export public key
$ openssl ec -in secp256k1-key.pem -pubout -out ecpubkey.pem
  • 生成的私钥内容如下:
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIO/oTB61Jef6zBanUeWXUmyHIKQE6RCKuriskrNfee3AoAcGBSuBBAAK
oUQDQgAEBgmGjRWN+oZwehgqEmalK6YtMPgC/m1nkUE+YTymDp3sJ4L+VIAF7mrN
gPimd79cG37U2bn41bZIjGS2qXVjUA==
-----END EC PRIVATE KEY-----
  • 生成的公钥内容如下:
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1xy6i/50bcje4mrDWIGL729DDdHFtCz9
t4VCfr8KP5WyLH5+0FPB4qnwhVOrpg2CZi3UVOW44+hGqQke2eeURQ==
-----END PUBLIC KEY-----
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值