摘要
本文介绍一款开源密码管理工具onepw。
在密码管理器中1Password
,KeePass
都是大名顶顶,都有UI界面,而这里要讲的onepw
则是一款命令行下的密码管理器。onepw
仅仅只有几个命令: init
,add
,rm
,ls
,find
。onepw
使用AES-256加密算法和CFB加密模式对密码和帐号进行加密,为每个帐号和密码随机一个初始化向量(IV)。
工作原理
1) 生成AES加密算法所需的Key(Key是不能记录下来的),它由牢记于你心中的主密码得到。
+--------+ +-----+
| Master | MD5Sum | |
| Pass |========>| Key |
| Word | | |
+--------+ +-----+
2) 对帐号和密码分别按下面的流程进行加密
+-----------+
| |
| Random IV |==|
| | | +------------+
+-----------+ | CFB Encrypter | |
|===============>| CipherText |
+-----------+ | AES Cipher | |
| | | with Key +------------+
| PlainText |==|
| |
+-----------+
加密部分的代码如下:
func (box *Box) encrypt(pw *Password) error {
block, err := aes.NewCipher([]byte(md5sum(box.masterPassword)))
if err != nil {
return err
}
if len(pw.AccountIV) != block.BlockSize() {
pw.AccountIV = make([]byte, block.BlockSize())
// crand aliases crypto/rand
if _, err := crand.Read(pw.AccountIV); err != nil {
return err
}
}
if len(pw.PasswordIV) != block.BlockSize() {
pw.PasswordIV = make([]byte, block.BlockSize())
if _, err := crand.Read(pw.PasswordIV); err != nil {
return err
}
}
pw.CipherAccount = cfbEncrypt(block, pw.AccountIV, []byte(pw.PlainAccount))
pw.CipherPassword = cfbEncrypt(block, pw.PasswordIV, []byte(pw.PlainPassword))
return nil
}
func cfbEncrypt(block cipher.Block, iv, src []byte) []byte {
cfb := cipher.NewCFBEncrypter(block, iv)
dst := make([]byte, len(src))
cfb.XORKeyStream(dst, src)
return dst
}
好了,onepw
的核心其实就这点了,此外就是命令包装,用来对密码盒进行管理。一般来说,onepw
的使用工作流如下:
设置环境变量
export ONEPW_FILE="/home/user/mypasswords/password.data"
export ONEPW_MASTER="XXXYYYZZZ"
init
使用 init 命令进行初始化,这将创建一个密码本文件 $ONEPW_FILE。需要说明的是,任何对密码的查看和操作都需要提供主密码,为避免频繁输入,可设置 ONEPW_MASTER
环境变量,onepw
会尝试读取这个环境变量
onepw init
add
使用 add 命令添加新密码或更新原密码
- 如果
add
命令没有指定--id
参数,则为添加新密码 - 否则更新指定 ID 的密码,若 ID 不存在则报错
- 可以指定
--tag
,--site
等参数对密码存储一些额外信息 - 虽然可以通过
--pw
和--cpw
参数指定密码和确认密码,但是建议不指定这些参数,而是由提示 type the password 或 repeat the password 后输入完成
onepw add -c email -u user@example.com
上面这条命令执行后会在终端输出 type the password 的提示,此时输入密码,然后会输出 repeat the password 的提示,再重复刚才的密码即可。目前仅要求密码长度至少6个字符,将来将加入一些别的强制性安全要求。
list
使用 list 命令查看当前已有的所有密码(ls 是 list 命令的别名)
onepw ls
命令的输出像这样
+---------+----------+------------------+----------+---------------------------+
| ID | CATEGORY | ACCOUNT | PASSWORD | UPDATED_AT |
+---------+----------+------------------+----------+---------------------------+
| d9437f0 | email | user@example.com | 123456 | 2016-04-29T07:54:36+08:00 |
+---------+----------+------------------+----------+---------------------------+
remove
使用 remove 命令根据ID前缀删除密码(rm,del,delete 是 remove 命令的别名)
onepw remove d9
- remove 指令可以一次删除多个密码,只需要输入多个ID参数即可,像这样:
onepw rm ID1 ID2 ...
- 如果指定的某个ID前缀有歧义(即存在2个及以上的密码的ID包含此前缀),那么删除将失败,除非指定
-a
或--all
标记 - 如果没有指定任何ID,而提供了
-a
或--all
参数则将清空所有密码
find
使用 find 命令查找密码
onepw find email
find 命令需要一个参数作为匹配文本(暂不支持正则表达式),然后从每个密码的 ID,Category,Account,Password,Tags,Site中检测是否包含此文本,如果是,此密码将列入到结果中显示
generate
使用generate
命令生成密码, gen
是generate
的别名.
onepw gen 16
输入onepw gen -h
获取帮助.
info
使用 info
命令查看密码的详细信息
额外的话
onepw
完全可以在本地进行密码的管理,也可以自行同步到云端,无论如何,都建议做版本管理。比如自己在本地建立一个git仓库,每次操作密码后做一次提交,这样中途如果出现误操作也可通过版本系统进行恢复。同时可以在bitbucket上创建一个私人仓库,将密码托管其上,从此只需记住主密码,到哪儿都可以进行密码管理了。
主密码千万要记住且保密了
onepw
虽然从功能上讲基本够用,但是如果有各种平台的UI,使用起来会方便许多。后面将会对onepw
进行一些优化和安全强化,完了,开发UI界面进行可视化管理。
onepw
开源在github上 https://github.com/mkideal/onepw,命令行接口使用https://github.com/mkideal/cli 构建。
有疑问加站长微信联系(非本文作者)
