目錄
一、OpenSSH和ssh-keygen
OpenSSH是SSH協議的開源版本(SSH:Secure SHell)。使用SSH透過計算機網絡實現加密通訊,可以進行遠程控制,在計算機之間傳送文件等等。SSH傳輸的數據都進行了加密,比telnet,rcp,ftp,rlogin,rsh等以明文傳輸密碼的工具更安全。
OpenSSH提供了實現SSH協議的很多工具。其中ssh-keygen用於生成,管理和轉換用於認證的密鑰和證書。
ssh-keygen
- -b <bits> 密鑰長度,默認為2048
- -t <type> 密鑰類型, rsa|des... (默認類型為rsa)
- SSH1: RSA
- SSH2: RSA, DSA, ECDSA
- -N <password> 新密碼
- -f <file> 指定密鑰文件,創建時會同時生成一個.pub結尾的公鑰文件。
- -C <comment>
- -c 修改公鑰或私鑰文件中的注釋
- -p 修改私鑰文件密碼
- -P <password> 舊密碼
- -e 導出為其它格式的密鑰文件,可以轉換密鑰類型
- -i 從其他格式的密鑰文件導入,可以轉換密鑰類型
- -m <PEM|PKCS8|RFC4716> 與-e,-i配合使用,指明導出或導入的密鑰文件格式
- -y 讀入密鑰並顯示公鑰
二、OpenSSL
OpenSSL 是一個強大的安全套接字層密碼庫,包括了加密算法,常用密鑰和證書管理,SSL協議等功能。OpenSSL提供的命令非常多,這里只簡單列出OpenSSL生成密鑰和證書的一些操作(Window需要以管理員身份運行cmd)。
v1.0.1+密鑰默認采用PKCS#8格式(之前版本為PEM)。
查看openSSL版本
openssl version
openssl version -a
enc 對稱加密
1.密鑰生成(genrsa,genpkey,req在證書請求時同時生成密鑰, gendh, gendsa)
(1) openssl genrsa [options] [bits_num]
- -out <file> 指定輸出文件,不指定時在終端顯示密鑰內容
- -passout pass:<password> 設置私鑰文件密碼
- -f4 使用F4(0x10001)作為公鑰的E參數(默認)
- -3 使用3作為公鑰的E參數
- -des , -des3, -aes128, -aes192, -aes256 指定加密算法(默認不加密)
默認生產的密鑰格式為PEM。openssl默認只生成了私鑰文件,當需要提取公鑰時使用rsa命令。
示例
#生成RSA密鑰對。位長度為2048,保持到rsakey0.pem文件中。 openssl genrsa -out rsakey0.pem 2048
#生成RSA密鑰對。使用DES3加密,密鑰使用密碼保護,位長度為1024 openssl genrsa -des3 -out rootca.key -passout pass:123456 1024
(2) openssl genpkey [options] v1.0.1+
示例
#生成RSA密鑰,位長度為2048,格式為DER
openssl genpkey -algorithm RSA -out rsapriKey.pem -pkeyopt rsa_keygen_bits:2048 -outform DER
(3) openssl req請求時生成新的密鑰對
openssl req -x509 -days 365 -newkey rsa:2048 -keyout private.pem -out public.pem -nodes
2.密鑰文件管理和轉換(rsa, pkey)
(1) openssl rsa [options] <infile >outfile
- -in <infile> 輸入密鑰文件
- -passin pass:<password> 輸入密鑰保護密碼
- -inform <DER|NET|PEM> 輸入密鑰格式,默認為PEM
- -out <outfile> 輸出密鑰文件
- -outform <DER|NET|PEM> 輸出密鑰格式,默認為PEM
- -passout pass:<password> 輸出密鑰保護密碼
- -pubin 指示輸入的是公鑰,默認輸出的是密鑰對或私鑰
- -pubout 輸出公鑰到文件(公鑰一般無需加密)
- -des, -des3, -aes128, -aes192, -aes256 指定密鑰加密算法
- -text 明文輸出密鑰參數
- -noout 不輸出密鑰到文件
- -check 驗證一致性
- -modulus 顯示RSA密鑰模值
示例
#提取密鑰公鑰到單獨的文件 openssl rsa -in rsakey0.pem -pubout -out rsakey0.pub #轉換密鑰格式(DER->PEM) openssl rsa -in rsakeypair.der -inform DER -out rsakeypair.pem
#改加密算法,移除密碼保護
openssl rsa -in rsakeypair.pem -passin pass:123456 -des3 -out rsakeypair1.pem
(2) openssl pkey [options] v1.0.1+
(3) 將PEM格式密鑰轉換成Java JCE 能使用的DER格式密鑰的另一種方式
openssl pkcs8 -topk8 -inform PEM -outform DER -in <rsa_pem.key> -out <pkcs8_der.key> -nocrypt
(4) OpenSSL公鑰和OpenSSH公鑰格式轉換
OpenSSL生成的公鑰格式和OpenSSH公鑰格式不一致,把OpenSSL生成的公鑰用於配置SSH連接,驗證會失敗。
OpenSSL公鑰(PEM)格式為:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vbqajDw4o6gJy8UtmIbkcpnk O3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2 eHnHl5CB8ruRX9fBl/KgwCVr2JaEuUm66bBQeP5XeBotdR4cvX38uPYivCDdPjJ1 QWPdspTBKcxeFbccDwIDAQAB -----END PUBLIC KEY-----
OpenSSH公鑰格式為:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC7vbqajDw4o6gJy8UtmIbkcpnkO3Kwc4qsEnSZp/TR+fQi62F79RHWmwKOtFmwteURgLbj7D/WGuNLGOfa/2vse3G2eHnHl5CB8ruRX9fBl/KgwCVr2JaEuUm66bBQeP5XeBotdR4cvX38uPYivCDdPjJ1QWPdspTBKcxeFbccDw==
- 從私鑰重新生成OpenSSH格式公鑰
ssh-keygen -y -f priKey.pem > sshPubkey.pub
- 將OpenSSL格式公鑰轉換成OpenSSH格式
ssh-keygen -i -m PKCS8 -f sslPubKey.pub 〉 sshPubKey.pub #-m支持 PEM,PKCS8,RFC4716
- 將OpenSSH格式公鑰轉換成OpenSSL格式公鑰
ssh-keygen -e -m PEM -f sshPubKey.pub >sslPubKey.pub #-m支持 PEM,PKCS8,RFC4716
3.使用密鑰(rsautl),不支持大文件
openssl rsautl [options]
- -in <file> 輸入需加密解密文件
- -out <file> 輸出加密或解密后的文件
- -inkey <file> 輸入密鑰文件
- -passin pass:<password> 輸入密鑰文件的保護密碼
- -keyform <PEM|DER|NET> 輸入密鑰文件格式,默認為PEM
- -pubin 指明輸入的是公鑰文件
- -certin 指明輸入的是包含公鑰的證書
- -sign 使用私鑰簽名簽名(加密)
- -verify 似乎用公鑰驗證簽名(解密)
- -encrypt 使用公鑰加密
- -decrypt 使用私鑰解密
- -hexdump 輸出十六進制
- -pkcs, -ssl, -raw, -oaep 數據補齊方式,默認為pkcs
使用RSA加密時,要求被加密的數據長度與RSA密鑰長度一致,數據過短時會補齊。過長時會分段加密。實際應用中很少會使用非對稱加密算法對大的文件進行加密操作,而是使用對稱加密算法加密文件,然后再使用<非對稱加密算法>對<對稱算法的密鑰>進行加密。
示例:
#使用公鑰加密 openssl rsautl -in test.txt -out test_enc.txt -inkey rsakeypair.pub -pubin -encrypt #使用私鑰解密 openssl rsautl -in test_enc.txt -out text_dec.txt -inkey rsakeypair.pem -decrypt
#使用私鑰簽名
openssl rsautl -in test.txt -out test_sign.txt -inkey rsakeypair.pem -sign
#使用公鑰驗證簽名
openssl rsautl -in test_sign.txt -out test_unsign.txt -inkey rsakeypari.pub -pubin -verify
4.證書管理
- 生成X509格式的自簽名證書
openssl req -x509 -new -days 365 -key rsakey.pem -out cert0.crt
會要求輸入區別名DN的各項信息(國家,城市,組織,姓名,email等)。
根證書是認證中心機構(Certificate Authority)給自己簽發的證書,簽發者就是自身,是信任鏈的起點。里面包含了CA信息、CA公鑰、用自身的私鑰對這些信息的簽名。下載並使用根證書就表示你信任它的來源機構,自然也信任證書以下簽發的所有證書。某個證書可以用簽發他的證書中的公鑰驗證,簽發他的證書又需要上一層簽發證書來驗證,直到通過根證書中的公鑰驗證,那么這個證書就是可信任的。
- 生成要求根證書簽發子證書的請求文件
openssl req -new -key rsakey1.pem -out subcertreq.csr
會要求輸入區別名DN的各項信息(國家,城市,組織,姓名,email等),還需要額外屬性:密碼 和 可選公司名。
- 使用根證書簽發子證書
openssl x509 -req -in subcertreq.csr -CA cert0.crt -CAkey rsakey0.pem -CAcreateserial -days 365 -out subcert.crt
也可創建一個ca的配置文件,通過ca管理子命令來簽發子證書(未試驗)
openssl ca -config ca.config -out user.crt -infiles user.csr
- 將證書和密鑰打包為pkcs12格式的庫中
openssl pkcs12 -export -in subcert.crt -inkey rsakey1.pem -out subcert.p12
需要輸入pkcs12文件密碼。
- 查看證書內容
openssl x509 -noout -text -in rootca.crt
- 驗證證書
openssl verify -CAfile rootca.crt subcert.crt
用rootca.crt的公鑰驗證subcert.crt中的簽名
從證書中提取公鑰
openssl x509 -in cert.pem -noout -pubkey > pubkey.pem
提取密鑰對
openssl pkcs12 -in cert.pfx -nocerts -nodes -out keypari.pem
從PKCS#8提取公鑰
openssl req -in public.pem -noout -pubkey
查看pkcs7簽名內容的證書信息
openssl pkcs7 -in <pkcs7singedFile> -inform DER -print_certs
三、Keytool工具管理證書
keytool是Java提供的密鑰、證書和證書庫管理工具。可以完成生成密鑰,生成證書等各種操作。
keytool的子命令如下:
-certreq 生成證書請求
-changealias 更改條目的別名
-delete 刪除條目
-exportcert 導出證書
-genkeypair 生成密鑰對
-genseckey 生成密鑰
-gencert 根據證書請求生成證書
-importcert 導入證書或證書鏈
-importkeystore 從其他密鑰庫導入一個或所有條目
-keypasswd 更改條目的密鑰口令
-list 列出密鑰庫中的條目
-printcert 打印證書內容
-printcertreq 打印證書請求的內容
-printcrl 打印 CRL 文件的內容
-storepasswd 更改密鑰庫的存儲口令
還可以使用 keytool -command_name -help 查看各個子命令的幫助信息
- pkcs12庫中證書導入jks證書庫(java keystore格式)
keytool -importkeystore -srckeystore subcert.p12 -destkeystore subcert.jks -srcstoretype pkcs12
需要輸入目標庫的密碼和源庫的密碼,如果jks庫文件不存在的話會自動生成。
- 導入證書到jks庫
keytool -importcert -keystore subcert.jks -alias rootca -file rootcert.crt
需要輸入目標庫密碼和是否信任添加的證書。-alias可以省略,如果jks庫文件不存在的話會自動生成。
證書庫或者說密鑰庫中即可以存放密鑰也可存放證書,如果只包含證書(證書中有公鑰)而不包含私鑰,這樣生成的庫就是trust庫。
查看證書指紋
keytool -list -keystore <keystoreFile> -alias <aliasName>
等待補充......
四、GPG
先整理下三個概念:
- OpenPGP 是一種加密標准和協議(RFC4880)。
- PGP(Pretty Good Privacy)是這個標准的閉源商業實現。
- GPG(GnuPG)是這個標准的開源實現。
可見PGP和GPG是基於同一個標准的兩套獨立的工具,都能處理加解密、簽名等功能,GPG是開源免費的。
官方文檔:https://www.gnupg.org/documentation/manuals/gnupg/
GPG使用~/.gnupg目錄。GPG除了基本的GnuPG核心命令功能外,GPG提供了一個名為Kleopatra的GUI密鑰和證書管理工具,使用起來非常方便。Kleopatra的基本用法。
GPG命令詳解
-a 以ASCII輸出
功能選擇
--sign | -s 可以結合--encrypt或--symmetric或兩者同時使用。使用默認的密鑰。選擇密鑰使用--local-user和--default-key選項。
--clearsign 簽名,內容可讀。選擇密鑰使用--local-user和--default-key選項。
--detach-sign | -b 創建獨立的簽名
--encrypt | -e 非對稱加密,可以結合--sign,--symmetric或兩者同時使用
-c | --symmetric 對稱加密。默認輸出擴展名為.gpg,可以用-o指定輸出文件,默認加密算法為CAST5,可以結合--cipher-algo指定算法。也可以配合--sign或--encrypt或兩者同時使用。
等待補充......
示例:(http://blog.chinaunix.net/uid-9525959-id-2001824.html)
gpg -c myfile [-o myfile.gpg] #對稱加密 gpg -d myfile.gpg -o myfile.decrypt #對稱解密 gpg --genkey #交互式創建密鑰 gpg --list-keys #查看已有的密鑰 gpg -e -a -r privkey file [-o descfile] #加密(需要公鑰)。 -e | --encryt, -a ASCII輸出, -r 指定加密的用戶ID。 gpg -o descfile --decrypt file.asc #解密(需要私鑰),會提示輸入密鑰密碼。 gpg -o pubkeyfile --export KeyID [-a] #導出公鑰(證書),如果未指定KeyID,則備份所有公鑰, -a ASCII輸出否則為二進制格式。 gpg -o subkeyfile --export-secret-keys KeyID [-a] #導出私鑰 gpg --import subkeyfile #導入私鑰 gpg -o signedfile -s file #簽名(需要私鑰) gpg -o txtsignedfile --clearsign file #保護原文的簽名 gpg --verify signedfile #驗證簽名(需要公鑰) gpg -o encryptsignedfile -ser prikey file #簽名並加密(恢復時驗證,不能通過--verify直接驗證) gpg -o file --decrypt encryptsignedfile #恢復加密的簽名文件並驗證 gpg -o filesign -b -a file #-b分離的簽名,生成文件只包含簽名信息 gpg --verify filesign file #分離的簽名驗證 gpg --edit-key userID #編輯公鑰,進入自命令環境:fpr 查看指紋, sign 簽署公鑰(加密是不再產生警告),check 檢查已有的鑰匙的簽名, quit 退出
五、PGP
PGP是OpenPGP標准的閉源商業版本。pgp提供了圖形化工具和命令行工具,命令行工作主要有以下幾個:
- pgpk.exe 密鑰生成和管理
- pgpe.exe 加密
- pgps.exe 簽名
- pgpv.exe 解密和校驗
- pgpo.exe 模擬2.6.3老版本命令行方式
示例(http://blog.chinaunix.net/uid-7673620-id-2598657.html)
pgpk -g #交互式生產密鑰 pgpk -x keyname [-o pubkeyfile] #導出公鑰 pgpk -a pubkeyfile #將密鑰加入密鑰環(pubring.pkr文件) pgpk -r keyname #從密鑰環刪除公鑰 pgpe -r keyname originfile [-o encryedfile] [-a] #加密,-a表示生成ASCII文檔而不是二進制 pgpv encrypedfile -o decryedfile #解密(需要密鑰密碼) pgps -u keyname originfile [-o signedfile] [-a] #簽名(需要密鑰密碼),-a表示生成ASCII文檔而不是二進制 pgpv signedfile #簽名驗證並恢復原始文件 pgp -ka KEYS #導入密鑰 pgp file.asc #驗證簽名
六、PuTTY工具
Putty是一個免費小巧(主程序只有300多K)的Window/Unix平台的ssh,telnet客戶端,附帶xterm終端模擬器。功能絲毫不遜於商業的SecureCrt。官方網站:http://www.chiark.greenend.org.uk/~sgtatham/putty/。
PuTTY包含多個工具。
- PuTTY telnet和SSH客戶端
- PSCP SCP客戶端
- PSFTP SFTP客戶端
- PuTTYtel telnet客戶端
- Plink PuTTY后端的命令行接口
- Pageant SSH認證代理,(PuTTY、PSCP、PSFTP、Plink都會用到)
- PuTTYgen RSA和DSA密鑰生成轉換工具
PuTTYgen
本文主要內容是密鑰的管理,所有只說明PuTTYgen的使用。
PuTTYgen使用的密鑰存儲格式類似於OpenSSL(密鑰文件擴展名.ppk,其中同時包含公鑰和私鑰)。
公鑰格式
---- BEGIN SSH2 PUBLIC KEY ---- Comment: "imported-openssh-key" AAAAB3NzaC1yc2EAAAABIwAAAQEA5of83WbXgRVTUFsOI49wacuEp253YuzZW1Lk ...... vw7Oc6o357ipDPgWk9c82s+7Asov4OgX5o6hg3R7418Gc0lkqw== ---- END SSH2 PUBLIC KEY ----
私鑰格式(.ppk)
PuTTY-User-Key-File-2: ssh-rsa Encryption: aes256-cbc Comment: imported-openssh-key Public-Lines: 6 AAAAB3NzaC1yc2EAAAABIwAAAQEA5of83WbXgRVTUFsOI49wacuEp253YuzZW1Lk ...4行...
...... vw7Oc6o357ipDPgWk9c82s+7Asov4OgX5o6hg3R7418Gc0lkqw== Private-Lines: 14 xc2m3BR30d7GZG/QVatu8Xm5PfYYMXRfPobGtbqLsWWI9Wzfjs/InEVFPcG8kJ6v ...12行... GANvUGQcgCyQTKVnqXmSMwPNZkqkJYZmRA43PBfiufVLV4JItNxY8ol+enUfWwde Private-MAC: 647a57a82038c05113fbd6a1758871b138a7a001
可以導入和導出OpenSSH和ssh.com格式的私鑰(Conversions菜單下)。程序主界面中也會顯示OpenSSH格式的公鑰。
-----------------------------未整理----------------------------------
其他
OpenSSL生成的密鑰文件(.pem),簽發請求文件(.csr)和證書文件(.cet)都是用純文本格式保存了Base64編碼后的信息(PEM格式)。可以用文本編輯器打開,內容如下:
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEArlUX2v998Y+Ek/AzoDdsbW7ILyRpwXVBMDqmOf3ZZpbP/4vo
.....省略若干行......
buL0a0BOFi7dyJjWgtEyYTFQgYSeezHl/+XyOhuJlTyvZWUpm5w=
-----END RSA PRIVATE KEY-----
首行和末尾行會被忽略,首行中顯示了文件中存儲的信息類型。
查看簽名信息
jarsigner -verify -verbose -certs <jksSignedFile>
PEM格式 (PKCS#8)
pem是最常用的私鑰和證書存儲格式。其中通常會包含 ‘—–BEGIN XXXX—–” and “—–END XXXX—–” 字符串,中間存放了Base64編碼過的二進制數據。多個PEM證書或私鑰可以包含在一個文件中,但最好還是將各個證書和私鑰分開存放。擴展名可能為.pem, .crt, .cer, .key。
ASN格式
DER格式
主要用在Java,所有類型的證書和私鑰都能用DER格式存放。文件中直接存儲二進制數據,未進行Base64編碼,無可讀性的描述文字。擴展名可能為.cer, .der。
PVK格式(微軟)
NET格式
P7B/PKCS#7文件(PEM)
包含 “—–BEGIN PKCS—–” & “—–END PKCS7—–” 字符串,只能存儲證書和鏈證書,不能存放私鑰。內容經過Base64編碼,擴展名可能為.p7b,.p7c
PFX/PKCS#12文件(PEM)
可以加密的文件,可在一個文件中存放多個證書或密鑰,主要用於證書和私鑰的導入導出。擴展名一般為.pfx, .p12
PEM轉DER
openssl x509 -outform der -in certificate.pem -out certificate.der
PEM格式證書轉P7B
openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfileCAcert.cer
PEM格式轉PFX
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt-certfile CAcert.crt
DER轉PEM
openssl x509 -inform der -in certificate.cer -out certificate.pem
P7B轉PEM
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
P7B轉PFX(先轉成PEM)
$ openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
$ openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -outcertificate.pfx -certfile CAcert.cer
PFX轉PEM(PFX中所有內容被存放到一個pem格式文件中)
openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes
PKCS#8定義了私鑰信息語法和加密私鑰語法,X509定義證書規范,密鑰通常使用DER和PEM進行編碼存儲,Java中JCE使用的是DER。openssl主要用的是PEM編碼。PEM相對DER可讀性更強,以BASE64編碼,外圍包上類似----BEGIN RSA PRIVATE KEY----。 JCE沒有對PEM直接支持,但是第三方那個包如bouncycastle可以解析。
很多SSH公鑰使用openssh格式。其內容為ssh-rsa打頭,RSA-1024結尾,中間是Base64編碼:
ssh-rsa AAAAB3Nza.........................cySYqQ== RSA-1024
參考資料:
OppenSSL文檔: https://www.openssl.org/docs/apps/openssl.html
Keytool文檔:http://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html
http://zhtx168.blog.163.com/blog/static/41601548200812503248/
http://blog.csdn.net/kimylrong/article/details/43525333
http://blog.csdn.net/jiftlixu/article/details/19836405
http://blog.csdn.net/zhymax/article/details/7683925
http://www.360doc.com/content/13/1203/17/14797374_334193770.shtml