27 Stronghold

原文链接: https://tauri.app/plugin/stronghold/

使用 IOTA Stronghold 密钥管理引擎存储密钥与敏感数据。

支持的平台

平台支持程度说明
Windows完整支持
Linux完整支持
macOS完整支持
Android完整支持
iOS完整支持

设置

自动

使用你的项目包管理器添加依赖:

1
npm run tauri add stronghold
1
yarn run tauri add stronghold
1
pnpm tauri add stronghold
1
deno task tauri add stronghold
1
bun tauri add stronghold
1
cargo tauri add stronghold

手动

  1. 在 src-tauri 文件夹中运行以下命令,把插件加入 Cargo.toml 里的项目依赖:

    1
    
    cargo add tauri-plugin-stronghold
    
  2. 修改 lib.rs 初始化插件:

    1
    2
    3
    4
    5
    6
    7
    
    #[cfg_attr(mobile, tauri::mobile_entry_point)]
    pub fn run() {
        tauri::Builder::default()
            .plugin(tauri_plugin_stronghold::init())
            .run(tauri::generate_context!())
            .expect("error while running tauri application");
    }
    
  3. 用你偏好的 JavaScript 包管理器安装 JavaScript 端绑定:

1
npm install @tauri-apps/plugin-stronghold
1
yarn add @tauri-apps/plugin-stronghold
1
pnpm add @tauri-apps/plugin-stronghold
1
deno add npm:@tauri-apps/plugin-stronghold
1
bun add @tauri-apps/plugin-stronghold

用法

插件必须用一个密码哈希函数初始化,该函数接收密码字符串,并必须返回由它派生的 32 字节哈希。

使用 argon2 密码哈希函数初始化

Stronghold 插件提供了一个使用 argon2 算法的默认哈希函数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
use tauri::Manager;

pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            let salt_path = app
                .path()
                .app_local_data_dir()
                .expect("could not resolve app local data path")
                .join("salt.txt");
            app.handle().plugin(tauri_plugin_stronghold::Builder::with_argon2(&salt_path).build())?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

使用自定义密码哈希函数初始化

或者,你可以使用 tauri_plugin_stronghold::Builder::new 构造函数提供自己的哈希算法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pub fn run() {
    tauri::Builder::default()
        .plugin(
            tauri_plugin_stronghold::Builder::new(|password| {
                // 在这里用 argon2、blake2b 或任何其它安全算法对密码做哈希
                // 下面是使用 `rust-argon2` crate 对密码做哈希的示例实现
                use argon2::{hash_raw, Config, Variant, Version};

                let config = Config {
                    lanes: 4,
                    mem_cost: 10_000,
                    time_cost: 10,
                    variant: Variant::Argon2id,
                    version: Version::Version13,
                    ..Default::default()
                };
                let salt = "your-salt".as_bytes();
                let key = hash_raw(password.as_ref(), salt, &config).expect("failed to hash password");

                key.to_vec()
            })
            .build(),
        )
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

从 JavaScript 使用

stronghold 插件在 JavaScript 中可用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { Client, Stronghold } from '@tauri-apps/plugin-stronghold';
// 使用 `"withGlobalTauri": true` 时,你可以这样写
// const { Client, Stronghold } = window.__TAURI__.stronghold;
import { appDataDir } from '@tauri-apps/api/path';
// 使用 `"withGlobalTauri": true` 时,你可以这样写
// const { appDataDir } = window.__TAURI__.path;

const initStronghold = async () => {
	const vaultPath = `${await appDataDir()}/vault.hold`;
	const vaultPassword = 'vault password';
	const stronghold = await Stronghold.load(vaultPath, vaultPassword);

	let client: Client;
	const clientName = 'name your client';
	try {
		client = await stronghold.loadClient(clientName);
	} catch {
		client = await stronghold.createClient(clientName);
	}

	return {
		stronghold,
		client,
	};
};

// 向 store 插入一条记录
async function insertRecord(store: any, key: string, value: string) {
	const data = Array.from(new TextEncoder().encode(value));
	await store.insert(key, data);
}

// 从 store 读取一条记录
async function getRecord(store: any, key: string): Promise<string> {
	const data = await store.get(key);
	return new TextDecoder().decode(new Uint8Array(data));
}

const { stronghold, client } = await initStronghold();

const store = client.getStore();
const key = 'my_key';

// 向 store 插入一条记录
insertRecord(store, key, 'secret value');

// 从 store 读取一条记录
const value = await getRecord(store, key);
console.log(value); // 'secret value'

// 保存你的更新
await stronghold.save();

// 从 store 移除一条记录
await store.remove(key);

权限

默认情况下,所有有潜在危险的插件命令和作用域都被阻止,无法访问。你必须在 capabilities 配置中修改权限才能启用它们。

更多信息请参阅能力概述,以及使用插件权限的分步指南。

1
2
3
4
5
6
{
  "permissions": [
    ...,
    "stronghold:default"
  ]
}
最后修改 September 26, 2026: 更新 (630b11f59)