zalando/go-keyring
GitHub: zalando/go-keyring
一个跨平台的 Go 库,通过统一接口访问操作系统原生 keyring 服务来安全存取密码凭证。
Stars: 1301 | Forks: 118
# Go Keyring 库
[](https://goreportcard.com/report/github.com/zalando/go-keyring)
[](https://godoc.org/github.com/zalando/go-keyring)
`go-keyring` 是一个跨操作系统的库,用于从系统 keyring 中*设置*、*获取*和*删除*
密码。它支持 **OS X**、**Linux/BSD (dbus)** 和
**Windows**。
go-keyring 的创建是因为其作者寻找过但无法找到更好的替代方案。它的目的是简化
静态链接二进制文件的使用,当依赖 C 绑定时(像其他 keyring 库那样),这通常非常麻烦。
#### 潜在用途
如果你正在开发一个需要在用户本地机器上存储用户凭证的应用程序,
go-keyring 可能会派上用场。例如,如果你正在为一个
需要用户名和密码的 API 编写 CLI,你可以将这些信息存储在
keyring 中,而不是让用户在每次调用时都输入。
## 依赖项
#### OS X
OS X 的实现依赖于 `/usr/bin/security` 二进制文件来与
OS X keychain 交互。它应该在默认情况下可用。
#### Linux 和 *BSD
Linux 和 *BSD 的实现依赖于 [Secret Service][SecretService] dbus
接口,该接口由 [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring) 提供。
预期 keyring 中存在默认集合 `login`,因为
它是大多数发行版的默认设置。如果它不存在,你可以通过
keyring 前端程序 [Seahorse](https://wiki.gnome.org/Apps/Seahorse) 创建它:
* 打开 `seahorse`
* 转到 **File > New > Password Keyring**
* 点击 **Continue**
* 当要求输入名称时,使用:**login**
## 使用示例
如何从 keyring 中*设置*和*获取*密码:
```
package main
import (
"log"
"github.com/zalando/go-keyring"
)
func main() {
service := "my-app"
user := "anon"
password := "secret"
// set password
err := keyring.Set(service, user, password)
if err != nil {
log.Fatal(err)
}
// get password
secret, err := keyring.Get(service, user)
if err != nil {
log.Fatal(err)
}
log.Println(secret)
}
```
## 直接使用 CLI
虽然这个库提供了一个方便的 Go API,但你也可以使用特定于操作系统的命令行工具直接与系统 keyring 交互。这对于调试、编写脚本或了解该库的底层运作很有用。你可以使用 CLI 从脚本中设置密码,然后从 Go 中访问它们,反之亦然。
### macOS
macOS 使用 `security` 命令与 Keychain 交互。
**设置密码:**
```
security add-generic-password -U -s "service" -a "user" -w "password"
```
**获取密码:**
```
security find-generic-password -s "service" -wa "user"
```
**删除密码:**
```
security delete-generic-password -s "service" -a "user"
```
其中:
- `-s` 指定服务名称
- `-a` 指定账户/用户名
- `-w` 指定要存储的密码
- `-U` 如果密码已存在则更新
- `-wa` 中的 `w` 选项仅输出密码值
### Linux 和 *BSD
Linux 和 *BSD 系统通过 D-Bus 使用 Secret Service API。从命令行与它交互的最简单方法是使用 `secret-tool`,它是 libsecret 的一部分。
**安装 secret-tool(如果尚未安装):**
```
# Debian/Ubuntu
sudo apt-get install libsecret-tools
# Fedora/RHEL
sudo dnf install libsecret
# Arch Linux
sudo pacman -S libsecret
```
**设置密码:**
```
secret-tool store --label="Password for 'user' on 'service'" service "service" username "user"
# 系统将提示您输入密码
```
或者直接提供密码:
```
echo -n "password" | secret-tool store --label="Password for 'user' on 'service'" service "service" username "user"
```
**获取密码:**
```
secret-tool lookup service "service" username "user"
```
**删除密码:**
```
secret-tool clear service "service" username "user"
```
注意:`service` 和 `username` 是用于标识密码的属性。标签是人类可读的描述。
### Windows
Windows 使用凭据管理器,可以通过 `cmdkey` 或 PowerShell 访问。
**使用 cmdkey:**
**设置密码:**
```
cmdkey /generic:"service:user" /user:"user" /pass:"password"
```
**获取密码:**
`cmdkey` 不支持直接获取密码。请改用 PowerShell:
```
$cred = Get-StoredCredential -Target "service:user"
$cred.GetNetworkCredential().Password
```
或者通过 PowerShell 使用 Windows API:
```
[System.Net.NetworkCredential]::new("", (Get-StoredCredential -Target "service:user").Password).Password
```
**删除密码:**
```
cmdkey /delete:"service:user"
```
**在 PowerShell 中使用 CredentialManager 模块:**
首先,安装 CredentialManager 模块:
```
Install-Module -Name CredentialManager -Force
```
**设置密码:**
```
New-StoredCredential -Target "service:user" -UserName "user" -Password "password" -Type Generic -Persist LocalMachine
```
**获取密码:**
```
(Get-StoredCredential -Target "service:user").GetNetworkCredential().Password
```
**删除密码:**
```
Remove-StoredCredential -Target "service:user"
```
注意:在 Windows 上,该库将服务和用户名组合为 `service:username` 用作凭据目标名称。
## 测试
### 运行测试
运行测试很简单:
```
go test
```
你使用的是哪种操作系统*确实*很重要。如果你使用的是 **Linux** 或 **BSD**,它将
测试 `keyring_unix.go` 中的实现。如果在
**OS X** 上运行测试,它将测试 `keyring_darwin.go` 中的实现。
### 模拟
如果你需要在没有 keyring 实现的系统上模拟 keyring 行为进行测试,你可以调用 `MockInit()`,它会将操作系统定义的提供程序替换为内存中的提供程序。
```
package implementation
import (
"testing"
"github.com/zalando/go-keyring"
)
func TestMockedSetGet(t *testing.T) {
keyring.MockInit()
err := keyring.Set("service", "user", "password")
if err != nil {
t.Fatal(err)
}
p, err := keyring.Get("service", "user")
if err != nil {
t.Fatal(err)
}
if p != "password" {
t.Error("password was not the expected string")
}
}
```
## 联系方式
* 电子邮件:
* 安全问题:请向[维护者](MAINTAINERS)发送电子邮件,我们将尝试在两个工作日内回复你。如果你没有收到回复,请发送电子邮件至 ,有人最多会在五天内回复。
## 许可证
请参阅 [LICENSE](LICENSE) 文件。
标签:EVTX分析, Go, Ruby工具, 凭据管理, 密码存储, 开发库, 日志审计, 系统密钥环