最近经常用 Node.js 写一些本地运行的脚本,需要安全的读取一些密钥密码之类的敏感信息,业界通常的做法是这样:
对于环境变量模式,一般情况需要在本地文件系统明文保存一些关键的密钥信息。本质上还是不太安全,例如你的钱包私钥明文放在本地文件系统,容易在未来的某一天爆雷,这种模式本质上不是无密码(Keyless)的。
对于 KMS 模式,需要依赖各种在线 KMS 服务,整体方案比较重,不太适合在本地电脑上轻量化使用。
本文使用 1Password 和官方提供的 CLI,在本地以无密码方式读取敏感信息。
brew install 1password-cli。具体可参考:https://developer.1password.com/docs/cli/get-started/op account addimport { exec } from 'child_process'
import util from 'util'
const execPromise = util.promisify(exec)
// 使用内存缓存存储密钥
const secretCache = new Map<string, string>()
async function getSecretFromOnePassword(itemName: string, label: string): Promise<string> {
const cacheKey = `${itemName}:${label}`
// 检查缓存中是否已存在
const cachedSecret = secretCache.get(cacheKey)
if (cachedSecret) {
console.log('从缓存获取密钥')
return cachedSecret
}
console.log('从 1Password 获取密钥...')
try {
// 使用 op cli 获取 JSON 格式的 item 数据
/*
返回值示例:
{
"id": "xxx",
"section": {
"id": "add more"
},
"type": "CONCEALED",
"label": "secret-key",
"value": "xxx-value",
"reference": "op://xxx/secret-key"
}
*/
const command = `op item get "${itemName}" --fields label="${label}" --format json`
const { stdout } = await execPromise(command)
// 解析返回的 JSON 并返回值
const item = JSON.parse(stdout)
if (item && item.value) {
console.log('密钥获取成功')
// 存入缓存
secretCache.set(cacheKey, item.value)
return item.value
} else {
throw new Error(`label "${label}" not found in item "${itemName}"`)
}
} catch (error) {
console.error('从 1Password 获取密钥失败:', error)
throw error
}
}

在执行脚本时,系统会弹出 1Password 确认框,待你确认后,程序就可以获取到对应的密钥。

本文用 Node.js 示范了如何在本地以 Keyless 模式读取 1Password 里的密钥,实现原理本质上是包装调用了 1Password 官方的 CLI 程序,其他语言例如 Python、Java、Golang 之类的也可以很轻松的实现本文的逻辑。
这套方案特别适合加密货币钱包私钥或者 root 账号私钥之类敏感内容,通过本文的方案可以满足可信消费和安全存储。
本文原载于:baiyun.me
原文链接:https://baiyun.me/nodejs-keyless-read-1password-secrets
最近经常用 Node.js 写一些本地运行的脚本,需要安全的读取一些密钥密码之类的敏感信息,业界通常的做法是这样:
对于环境变量模式,一般情况需要在本地文件系统明文保存一些关键的密钥信息。本质上还是不太安全,例如你的钱包私钥明文放在本地文件系统,容易在未来的某一天爆雷,这种模式本质上不是无密码(Keyless)的。
对于 KMS 模式,需要依赖各种在线 KMS 服务,整体方案比较重,不太适合在本地电脑上轻量化使用。
本文使用 1Password 和官方提供的 CLI,在本地以无密码方式读取敏感信息。
brew install 1password-cli。具体可参考:https://developer.1password.com/docs/cli/get-started/op account addimport { exec } from 'child_process'
import util from 'util'
const execPromise = util.promisify(exec)
// 使用内存缓存存储密钥
const secretCache = new Map<string, string>()
async function getSecretFromOnePassword(itemName: string, label: string): Promise<string> {
const cacheKey = `${itemName}:${label}`
// 检查缓存中是否已存在
const cachedSecret = secretCache.get(cacheKey)
if (cachedSecret) {
console.log('从缓存获取密钥')
return cachedSecret
}
console.log('从 1Password 获取密钥...')
try {
// 使用 op cli 获取 JSON 格式的 item 数据
/*
返回值示例:
{
"id": "xxx",
"section": {
"id": "add more"
},
"type": "CONCEALED",
"label": "secret-key",
"value": "xxx-value",
"reference": "op://xxx/secret-key"
}
*/
const command = `op item get "${itemName}" --fields label="${label}" --format json`
const { stdout } = await execPromise(command)
// 解析返回的 JSON 并返回值
const item = JSON.parse(stdout)
if (item && item.value) {
console.log('密钥获取成功')
// 存入缓存
secretCache.set(cacheKey, item.value)
return item.value
} else {
throw new Error(`label "${label}" not found in item "${itemName}"`)
}
} catch (error) {
console.error('从 1Password 获取密钥失败:', error)
throw error
}
}

在执行脚本时,系统会弹出 1Password 确认框,待你确认后,程序就可以获取到对应的密钥。

本文用 Node.js 示范了如何在本地以 Keyless 模式读取 1Password 里的密钥,实现原理本质上是包装调用了 1Password 官方的 CLI 程序,其他语言例如 Python、Java、Golang 之类的也可以很轻松的实现本文的逻辑。
这套方案特别适合加密货币钱包私钥或者 root 账号私钥之类敏感内容,通过本文的方案可以满足可信消费和安全存储。
本文原载于:baiyun.me
原文链接:https://baiyun.me/nodejs-keyless-read-1password-secrets