同步操作将从 deepinwiki/wiki 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
[TOC]
[linux内核编译] 众所周知,我们这个世界上充满偷看隐私的罪恶。不过,linux用户有福气了,因为有一组很方便的工具,可以帮助你加密和解密文档。
2021/11 更新: 最近 openssh 升级,宣布即将弃用 rsa 算法,因此补充使用 ed25519 系列算法生成 gpg 密钥和 Openssh 密钥的内容。
非对称会产生两条钥匙,一条可以公开给别人,另一条自己藏好。别人用公钥加密信息,只有你的私钥才能解密。同样的,你私钥加密的信息,也只有公钥可以解密。
这好像挺对称的,非对称的意思指加密解密用的不是同一根钥匙。这究竟是怎么做到的?这里就不展开讨论了,毕竟密码学是挺复杂的东西。
一般来说,当你想发布可信信息,那么用私钥加密,对方用公钥能解密,说明这个信息是你发布的。这一过程主要目的是验证发布者的身份。
当你想获取信息,别人用公钥加密,只有你能解密查看信息,保证信息的安全性。这一过程叫加密,目的就是为了信息本身。
可见这两个过程目的性是不一样的,一个是确认身份,一个是为了数据保密,分别称为:签名和加密。如果你想将保密数据发给对方,那该怎么办?这时候靠的就不是你这对密钥,而是要得到对方的公钥,用他的公钥加密信息发给他。
你也许注意到这样做最根本的原因在于公钥是公开的,谁都能拿得到。而私钥只有本人才有一份。理解这一过程,就能灵活运用非对称加密技术了。
这套技术,唯一的缺陷,是怎么证明公钥是对方的,而不是第三方伪装的。只要能保证公钥是对方的,那么之间的加密就是完美的,因为还没有听说有什么能破解这套加密体系的新闻。
公钥
:密钥对中公开的钥匙,所有人都可以拥有,即私钥加密的信息是非保密的(所以私钥加密是没意义的,别人能用公开的公钥解密),但私钥加密身份是明确,可以确定当这段加密信息能用公钥解密时,加密方必然是私钥的拥有者。所以私钥的加密行为称为签名,而不是加密(没有保密性)。总结:私钥用来签名和解密,公钥用来加密。私钥
:密钥对中保密的钥匙。只有私钥主人拥有。即公钥加密的信息是保密的,但身份不确定,任何人都可以发加密信息给私钥的主人。签名
:私钥对一段信息进行加密,这个操作就能(让公钥持有者)确定加密者身份,这就是所谓签名。但实际操作中为了提高加密效率,并不对所有数据进行加密,而先对数据进行散列(哈希),再对散列值进行加密。密钥环
: 保存秘钥的机制,类比钥匙扣加密算法
: 根据一组密码信息(指导信息)将数据变换成一种不可识别的信息组织,并可恢复原值(解密)的一种算法。哈希算法
: 将任意长度数据演算出固定长度的字符串,并尽可能保证字符串唯一性的一种算法。常用于数据的签名(意思是可代表数据实体的一个短语,类似人名)证书
:为了安全交换秘钥的第三方协调者所签出的证明文件。密码短语
: Passphrase,为了进一步保护私钥文件而设的密码,每次使用私钥都会提示输入密码,推荐 AES 算法。指纹
: 对密钥文件演算出一段简短但能标识密钥的字符串。当我们拥有对方的公钥时,自然可以安全的发加密信息给对方,但是难点在于我们怎么安全的获得对方的公钥,而不是第三方伪造的。
PKI(公钥基础结构)引入证书的概念。
内容从技术角度来看,证书主要携带被签名主体的公钥,和签名。这个签名是CA的私钥加密然和用签名算法取得散列值得来的。这就保证了该证书是由CA签发,并保证不被第三方所修改。只要你相信CA,那么证书携带的相对方的公钥,必然是没经过修改的。当然,前提你必须先拥有正确的CA公钥,来验证证书自身的正确性。
可见,证书并不解决问题,只是压缩了问题,因为它一样是采用非对称加密技术,只是作为一个管理中枢,来集中管理秘钥的可信任问题。如果你能信任CA,那你就可以信任CA签署的任意证书,即通过解决CA的自身的可信问题,同时解决了数量庞大的关联秘钥信任问题。
SSL(安全套接字层)(过时)和TLS(传输层安全)是常见的使用证书的具体网络协议,HTTPS 安全链接基于此协议来保证网站通信的安全性。
工具包:
ssh工具可以登录远程服务器,除了密码登录,还可以支持用公钥私钥技术来自动登录。
默认位置:
支持的格式:
BEGIN SSH2 PUBLIC KEY
BEGIN PRIVATE KEY
BEGIN PUBLIC KEY
BEGIN RSA PRIVATE KEY
BEGIN RSA PUBLIC KEY
BEGIN OPENSSH PRIVATE KEY
ssh-rsa .... htqx@xxx.com
ssh-keygen 对密钥文件的操作逻辑有点怪异。它将转换任务设计成非常奇怪的数个命令。
ssh-keygen 工具的基本逻辑:
# 注意:私钥实际上是可以输出公钥的
# 也就是私钥本身包含公钥信息,而公钥只含公钥信息
# openssh 私钥 -> openssh 公钥
ssh-keygen -f xxx.key > xxx.pub
# openssh 私钥 -> 其他格式(原地转换)
ssh-keygen -f xxx.key -pN '' -m pem
# ed25519 密钥暂时还没支持
# 需要安装转换工具
sudo npm install -g sshpk
sshpk-conv -f xxx.key -p -t pem > xxx.pem
# 其他格式私钥 -> openssh 私钥(原地转换)
ssh-keygen -f xxx.pem -pN ''
# openssh -> 其他格式公钥(注意有些加密算法只有 ssh2 支持)
ssh-keygen -f xxx.key -em pem > xxx.pub.pem
# 其他格式 -> openssh
ssh-keygen -f xxx.pem -im pem > xxx.key
ssh-keygen -f xxx.pub -im pem > xxx.pub.pem
openssl 使用的公钥格式是 pkcs 8 的:
BEGIN PUBLIC KEY
openssl rsa -in htqx.key -out htqx.pem
openssl rsa -RSAPublicKey_in -in htqx.pub -out htqx.pem
openssl rsa -RSAPublicKey_out -in htqx.pem -out htqx.pub
私钥支持添加密码保护。
常用命令组合:
ssh-keygen -b 2048 -C "htqx@xxx.com" -m pem -f htqx.key
: 创建 pem 格式 2048 位私钥,注释标记 “htqx@xxx.com",私钥文件名 htqx.key ,公钥文件是 htqx.key.pub ,格式是 RFC4716 的。ssh-keygen -e -f htqx.key -m pem > htqx.pem
: 输出 pem 格式公钥ssh-keygen -p -N '' -f htqx.key
ssh-keygen -p -N '' -m pem -f htqx.key
ssh-keygen -lf htqx.key
# 创建秘钥对
# -t 选择算法
# -b 长度
# -C 标识
# 接下来提示输入私钥文件名
# 如 xxx 产生 xxx(私钥)/xxx.pub(公钥)
# 然后输入该文件本身的密码,可以省略
ssh-keygen -t rsa -b 4096 -C "htqx@xxx.com"
ssh的管理目录在用户目录下 ~/.ssh/
# 打印公钥的指纹信息
# 指纹信息可以帮助用户快速对比秘钥信息
ssh-keygen -E md5 -lf xxx.pub
# 私钥托管到代理工具ssh-agent
ssh-add xxx
# 产生证书
# 产生CA自身的秘钥对
ssh-keygen -f htqx_ca
# 用户秘钥对
ssh-keygen -f htqx -C "htqx@xxx.com"
# 签署证书
# 产生 htqx-cert.pub 文件
ssh-keygen -s htqx_ca -I myid htqx.pub
ssh-keygen: 生成、管理、转换秘钥文件。
补充一个案例,最近(2021年11月),我发现连接 gitee 失败,之前是可以的。估计是系统的一个 bug,解决方案是修改 ~/.ssh/config
Host gitee.com
HostName gitee.com
User git
PubkeyAcceptedKeyTypes=+ssh-rsa # 增加这行
IdentityFile ~/.ssh/htqxgit_rsa # 俺的私钥
测试连接:
ssh -Tv gitee.com
# ...
# Hi htqx! You've successfully authenticated, but GITEE.COM does not provide shell access
openssl是一个很底层的强大密码学工具。一般会用他来创建证书。
openssl 加密算法 -in 原文件 -out 输出文件
openssl 加密算法 -d -in 加密文件 -out 输出文件
openssl 散列算法 文件
openssl pkeyutl -in 不大于116字节的文件 -out 输出 -encrypt -inkey 私钥
openssl rsautl -sign -inkey 私钥 -in 原文件散列 -out 签名
openssl rsautl -verify -inkey 公钥 -pubin -in 签名
openssl req -new -key 私钥 -nodes -out 证书请求.csr
openssl req -newkey rsa:2048 -nodes -keyout 新私钥 -out 证书请求.csr
openssl req -new -key 私钥 -config 配置文件 -out 证书请求.csr
openssl x509 -req -in 证书请求.csr -signkey 私钥 -out 证书.crt -days 3650 -extfile v3.ext
openssl req -x509 -key 私钥 -config 配置文件 -out 证书请求.csr
openssl verify -CAfile 签署私钥自身的证书 私钥所签署的证书
可以通过交互式提供证书请求文件需要的信息,也可以通过配置文件来批量生产证书请求文件。
信息:
请求配置文件(自动填写以上内容) csr.cnf:
[ req ]
encrypt_key = no
distinguished_name = dn
prompt = no
[ dn ]
C = CN
O = ktongsoft
CN = htqx
emailAddress = htqx@xxx.com
注意: x509 证书有两个版本,v1 和 v3, 默认是 v1 的,如果要签署 v3 证书,需要提供 v3 的扩展配置.
v3.ext:
subjectAltName = DNS:localhost
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
例子:
# 创建 25519 私钥
openssl genpkey -algorithm ED25519 > htqx3.key
# 请求证书
openssl req -new -out htqx3.csr -key htqx3.key -config htqx3.csr.cnf
# 签署 v3 版证书
openssl x509 -req -days 100 -in htqx3.csr -signkey htqx3.key -out htqx3.crt -extfile htqx3.ext
# 查看证书资料
openssl x509 -in htqx3.crt -text -noout
# 创建私钥
openssl genrsa -out ca.key 4096
# 导出公钥
openssl rsa -in ca.key -pubout -out ca.pub
# 创建x509证书(自签名)
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
# 给其他公钥签署证书
# 创建用户秘钥
openssl genrsa -out htqx.key 4096
# 用秘钥生成证书请求文件
openssl req -new -key htqx.key -out htqx.csr
# 用ca自签名证书和ca秘钥来签署证书请求文件,生成用户证书
openssl x509 -days 3 -CA ca.crt -CAkey ca.key -CAcreateserial -req -in htqx.csr -out htqx.crt
GPG是一个基于非对称加密技术的工具。开源世界很多地方实际使用的是这个工具。
它的优点:
sudo apt install gnupg
gpg --gen-key
生成密钥对,对话式。一般过程是要求你输入名字ID,邮箱,然后让你随意输入一大堆产生随机密钥的信息,随便打一大段就行了,过一段比较长的时间,它就会产生密钥对。还有可能让你输入私钥的访问密码。gpg --gen-revoke ID
根据名称id生成报废密钥对的一个证书,这个证书可以给第三方验证密钥有效性的机构使用。gpg --list-keys
列出系统有的密钥gpg --delete-key ID
删除指定id公钥gpg --delete-secret-keys ID
删除私钥gpg --output id.pub --export ID
输出指定ID的公钥文件,文件名:id.pubgpg --output id.key --export-secret-keys ID
输出私钥。gpg --fingerprint ID
根据id输出公钥的指纹信息。可以公布这个信息让持有公钥的人确认公钥是你的。gpg --send-keys ID --keyserver xxx
上传到第三方公钥存放服务器gpg --import 密钥文件
系统添加以文件存储的密钥gpg --keyserver xxx --search-keys ID
在第三方公钥存放服务器查找密钥记住:用自己的密钥对,能做的是签名和解密,所以放在这一节描述。
gpg --decrypt file.gpg
解密别人用你的公钥发给你的加密文件file.gpggpg --armor --detach-sign --output file.asc file
用私钥签名file文件,输出独立的签名文件file.asc,
--armor
表示输出文本而非二进制,--detach-sign
表示分离式签名,不合并原文件内容,这套参数我认为是比较合理的,因为签名往往需要在网站等场合公布出来,让别人验证。用别人的密钥对,能做的是验证对方身份,和加密信息发给对方。
gpg --recipient 对方ID --output file.gpg --encrypt file
首先你得安装对方公钥,得到对方id,然后加密file文件输出为file.gpg,这个文件就可以公开发送给对方,不需要担心别人截获该文件,因为只有对方用他的私钥才能解密。gpg --verify file.asc file
通过签名文件和原文件,可以验证签名,即文件没有被修改过,确实由密钥对持有者发出的原始文件。这个签名文件,对方可以在网站上贴出内容,因为是文本的。你只需要复制下来保存文件即可。当然,从技术上讲,你也可以加密发给自己。
单字添加前缀-,多字添加前缀
选项:
公钥私钥的保管是个问题,如果泄露了私钥,你可以声明撤销证书,但曾经签署的文件也都一同失效了。
为此,GPG 提出了子密钥(sub key)的概念。
pgp 密钥的能力:
主密钥和子密钥是类似的,但主密钥可以管理 S E A 类型的子密钥。
可以先创建好子密钥后,然后把主密钥移走,这样密钥也是可以工作的。这个有点类似 x509 的 ca 证书。
标识:
gpg --edit-key 用户
# 进入管理界面,用addkey 添加子密钥
首先是用 gpg 创建 SC 主密钥,然后创建导出给 openssl 的 A 子密钥,同时创建子密钥 E,和子密钥 S 备用。
创建主密钥的吊销证书备份。
保存私钥和公钥到文件备份。
第二步:
gpg 密钥环中删除 gpg 主密钥,保留子密钥。从而保护了主密钥。
第三步:
本来想从 gpg 导出给 openssh 使用的,但是,gpg 交互性不是很好,默认支持的是 rsa 算法,对 ed25519 的导出不支持。所以得独立生成 openssh 的密钥对。
另一个方案是 openssh 通过代理给 gpg 来管理密钥,从而使用 gpg 的 ed25519 密钥,方法:https://blog.mozcp.com/use-gnupg-agent-as-ssh-agent
# ed25519 密钥需要添加 expert 参数才有
# 选择 10 ECC(sign only)
# 选择 1 curve 25519 算法
# 选择证书的有效期,随你
# 输入识别id / email / 备注
# 最后需要提供一个稍微复杂的密码(大小写数字等)
gpg --expert --full-gen-key
# 密码是交互式的,如果想关闭密码提示,需要添加 --batch 批处理模式,但是这时候需要你提供所有的参数
# 类似下面的写法: passphrase 是密码, 最后是 id / 算法 / 用途 / 有效期
gpg --batch --expert --passphrase '' --quick-gen-key 'ktong (main) <htqx@xxx.com>' ed25519 sign none
# 列出私钥信息,如
# sec ed25519/16D4D7AA 2021-11-09 [SC]
# uid [ 绝对 ] ktong (gpg main key) <htqx@xxx.com>
# sec 表示密钥类型
# ed25519 算法
# 16d4d7aa 是密钥的短8位 id
# uid 是用户 id
# [绝对] 是系统对该密钥的信任程度
# --with-keygrip 列出在密钥环中的位置,这是 gpg 中唯一标识一个密钥对的方式
# --keyid-format 列出 id 的格式,short 是8位id,该 id 可用于命令上下文
# -K 私钥
# -k 公钥
gpg -K --keyid-format short
# 添加子密钥,进入交互模式
# help 显示可用命令
# quit 退出交互模式
gpg --expert --edit-key 16D4D7AA
# 添加子密钥,过程类似创建主密钥
# 选择的算法是 ECC(set your own capabilities) ,简而言之就是控制子密钥的用户,S 是签名, A 是身份认证
# ECC(encrypt only) 是 E 加密
addkey
save # 保存退出
# 这步完成之后,密钥信息应该类似:
sec ed25519/16D4D7AA 2021-11-09 [SC]
5438FE62374A7EBD32599F3E0DDF6E7C16D4D7AA
uid [ 绝对 ] ktong (gpg main key) <htqx@xxx.com>
ssb ed25519/05F7DEE4 2021-11-09 [A]
ssb ed25519/EFDBAE91 2021-11-09 [S]
ssb cv25519/3A3CB025 2021-11-09 [E]
# 接下来保存密钥对和吊销证书。主密钥可以吊销子密钥,吊销证书可以吊销主密钥,大概就是这么的关系
# 吊销证书
gpg -o ktong.sc.revoke --gen-revoke 16D4D7AA
# 私钥
gpg -o ktong.sc.key --export-secret-keys --armor 16D4D7AA
# 子密钥
gpg -o ktong.sc.sub --export-secret-subkeys --armor 16D4D7AA
# 公钥
gpg -o ktong.sc.pub --export-keys --armor 16D4D7AA
# 删除主密钥(连同子密钥一起删除)
gpg --delete-secret-key 16D4D7AA
# 重新导入子密钥
gpg --import ktong.sc.sub
# sec# ed25519/16D4D7AA 2021-11-09 [SC]
# 5438FE62374A7EBD32599F3E0DDF6E7C16D4D7AA
# uid [ 绝对 ] ktong (gpg main key) <htqx@qq.com>
# ssb ed25519/05F7DEE4 2021-11-09 [A]
# ssb ed25519/EFDBAE91 2021-11-09 [S]
# ssb cv25519/3A3CB025 2021-11-09 [E]
# sec# 表示主密钥并不在系统中
openssh 生成 ed25519 密钥对:
# 默认生成 id_ed25519 和 id_ed25519.pub 密钥对
ssh-keygen -t ed25519
不同的工具,原理上差不多,但是产生的秘钥文件的格式也许是不一样的。如果你想用同一对秘钥,那么就考虑一下转换他们之间的格式。
主要注意,密码系统使用的扩展名非常多,而且意义并不十分明确。同一个东西在不同的角度,可以使用不同的扩展名。
本文约定如下:
编码方式:
用途:
规范:
常见的秘钥文件格式:
PEM
: openssl 通用的秘钥格式,符合X.509标准的Base64编码。openssh
: openssh会产生这个私钥格式(但它也支持PEM)RFC4716
: SSH2 私钥和公钥的文件格式PKCS8
: 私钥机密格式PKCS#7
格式,加密数据和签名容器。PKCS#12
格式。公钥私钥合集。# 读取标准openssh私钥,输出PEM格式私钥
# 备份原秘钥,因为这个方式是通过修改密码
# 直接在原秘钥上复写的
mv -v xxx{,.bak}
ssh-keygen -m PEM -p -N "" -f xxx
# 反向
ssh-keygen -pN "" -f xxx
# 读取兼容公钥,输出PEM公钥
ssh-keygen -e -m PEM -f xxx.pub > xxx.pem
# 反向
ssh-keygen -i -m PEM -f xxx.pem
# 通过私钥输出公钥
ssh-keygen -f xxx -y
# 从 .pfx 到 pem 证书
openssl pkcs12 -in certificate.pfx -nokey -out certificate.crt
# 从 .pfx 到私钥(加密格式)
openssl pkcs12 -in certificate.pfx -out privatekey.key
# 从 .pfx 到 pem 私钥(rsa)
openssl rsa -in certificate.pfx -out privatekey_rsa.key
# 反向
openssl pkcs12 -export -in certificate.crt -inkey privatekey.key -out certificate.pfx
# 通过私钥导出公钥
openssl rsa -in privatekey_rsa.key -pubout -out publickey_rsa.key
# 通过证书导出公钥
openssl x509 -in certificate.crt -pubkey -out publickey_rsa.key
# 从 .der(.cer) 到 pem 证书
openssl x509 -inform der -in certificate.cer -out certificate.pem
# 反向
openssl x509 -outform der -in certificate.pem -out certificate.der
并不能直接转换。但是可以借助一个公共的桥梁,那就是 .p12 格式。gpg 有一个工具可以使用 p12 格式。
如果想要用原版的 gpg ,两种证书是无法沟通的,但是他们都支持 rsa 的密钥,共用同一个 rsa 密钥是可以的,但证书信息得重建。
gpgsm :
# 将公钥和私钥转换为 p12 格式
openssl pkcs12 --export -in db.crt -inkey db.key -out db.p12
# 导入
# gpgsm 是一个实用工具,它有类似 gpg 的参数形式,所以你可以把它当gpg来用(但有一些细微不同),它能够支持 p12 密钥。
gpgsm --import db.p12
gpg:
# monkeysphere 包
# 转换私钥格式
cat db.key | PEM2OPENPGP_USAGE_FLAGS=authenticate,sign,certify,encrypt pem2openpgp "htqx <htqx@xxx.com>" > db.pgp
# 再导入 gpg
gpg --import db.pgp
gpgsm:
# 查看私钥
gpg -K
# 导出 p12
gpgsm -o gpg.p12 --export-secret-key-p12 htqx
# 导出 pem(openssl 最喜欢的格式)
openssl pkcs12 -in gpg.p12 -out gpg.pem -nodes
# 生成 x509 证书
openssl x509 -in gpg.pem -out gpg.crt
# 查看证书信息
openssl x509 -in gpg.crt -text -noout
gpg:
# 导出 $KEYID 是证书的指纹
gpg --export $KEYID | openpgp2pem $KEYID > htqx.pub # 公钥
gpg --export-secret-key $KEYID | openpgp2pem $KEYID > htqx.key # 私钥
本案例将本人的 openssh 密钥,同时用在 openssl 和 gpg 的场合。
现有:
都是 openssh 的 ssh-keygen 生成的。
# 因为 openssl 支持 pkcs 1(也就是openssh 中的pem 格式) 的私钥
# 所以可以直接用。
# 不过 openssl 支持的公钥却是 pkcs 8 的。有点意思
# 但是有私钥就能导出公钥,所以并不需要特别的生成 pkcs8 的公钥
# 如果你的 openssh 私钥是 openssh 格式的,可以通过以下方式转换
cp -v htqxgit_rsa htqx.key # 转换是原地,最好备份
ssh-keygen -p -N '' -m pem -f htqx.key
# 证书请求文件
openssl req -new -key htqx.key -config csr.conf -out htqx.csr
# 如果懒得写配置文件(CN 写用途也可以)
openssl req -new -key htqx.key -subj "/CN=htqx/emailAddress=htqx@xxx.com/" -nodes -out htqx.csr
# 签署为正式证书(v3 版证书必须要提供 v3.ext 配置文件)
openssl x509 -req -in htqx.csr -signkey htqx.key -out htqx.crt -days 3650 -extfile v3.ext
openssl x509 -in htqx.crt -out htqx.cer -outform der # 二进制证书
# pgp 证书
# 导入同一个 私钥( x509 和 pgp 证书无法直接转换,只能共用同一个密钥)
cat htqx.key | PEM2OPENPGP_USAGE_FLAGS=authenticate,sign,certify,encrypt pem2openpgp "htqx <htqx@xxx.com>" | gpg --import
gpg -K # 查看刚导进来的密钥,记住指纹信息
gpg --edit-key 0E3A1C4B2F9C3E7842A0905472C5BD4D03B950C1
# 进入管理页面,设置信任,有效期等配置
gpg --export 03B950C1 > htqx.pgp # 导出公钥
gpg --export-secret-keys 03B950C1 > htqx.pgp.key # 导出私钥
密钥环即保存秘钥的区域,这个不同的密码系统可能保存在不同的地方。
密码:
根证书:
update-ca-certificates
# 图形管理工具
# 可以管理ssh, 证书, pgp, 密码四个区域
sudo apt install seahorse
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。