简单易用的密码管理工具

摘要

本文介绍一款开源密码管理工具onepw
在密码管理器中1PasswordKeePass都是大名顶顶,都有UI界面,而这里要讲的onepw则是一款命令行下的密码管理器。onepw仅仅只有几个命令: initaddrmlsfindonepw 使用AES-256加密算法和CFB加密模式对密码和帐号进行加密,为每个帐号和密码随机一个初始化向量(IV)。

screenshot.png

工作原理

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命令的帮助

  • 如果 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命令生成密码, gengenerate的别名.

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 构建。

共 0 个回复